diff options
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/common-utils.c | 219 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 6 | ||||
| -rw-r--r-- | libglusterfs/src/options.c | 183 | ||||
| -rw-r--r-- | libglusterfs/src/options.h | 3 | 
4 files changed, 269 insertions, 142 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 952af10c..f26d2bdc 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1586,47 +1586,79 @@ get_nth_word (const char *str, int n)  }  /* RFC 1123 & 952 */ - -/* The functions below validate given internet addresses and - * wildcard internet address for correctness. - * All return 1 on success and 0 on failure - */ - +/* Syntax formed combining RFC 1123 & 952                                     * +   <hname> ::= <first-name>*["."<gen-name>]                                   * +   <first-name> ::= <let-or-digit> <[*[<let-or-digit-or-hyphen>]<let-or-digit>] +   <gen-name> ::= <let>[*[<let-or-digit-or-hyphen>]<let-or-digit>]            */  char  valid_host_name (char *address, int length)  { -        int     i = 0; -        char    ret = 0; -        int     flag = 0; +        int             i = 0; +        int             str_len = 0; +        char            ret = 1; +        char            *dup_addr = NULL; +        char            *temp_str = NULL; +        char            *save_ptr = NULL; -        if ((length > 255) || (length == 1)) +        if ((length > _POSIX_HOST_NAME_MAX) || (length == 1)) { +                ret = 0;                  goto out; +        } -        if (!isalnum (address[length - 1])) +        dup_addr = gf_strdup (address); +        if (!dup_addr) { +                ret = 0;                  goto out; +        } +        temp_str = strtok_r (dup_addr,".", &save_ptr); -        for (i = 0; i < length; i++) { -                if (!isalnum (address[i]) && (address[i] != '.') -                    && (address[i] != '-')) +        /* first-name */ +        if (!temp_str || +            !isalnum(temp_str[0]) || +            !isalnum (temp_str[strlen(temp_str)-1])) { +                ret = 0; +                goto out; +        } +        for (i = 1; i < (strlen (temp_str) - 1); i++) { +                if (!isalnum (temp_str[i]) && (temp_str[i] != '-')) { +                        ret = 0;                          goto out; +                } +        } -                if (isalpha(address[i])) -                        flag = 1; +        /* gen-name */ +        while ((temp_str = strtok_r (NULL, ".", &save_ptr))) { +                str_len = strlen (temp_str); + +                if (!isalpha (temp_str[0]) || +                    !isalnum (temp_str[str_len-1])) { +                        ret = 0; +                        goto out; +                } +                for (i = 1; i < str_len; i++) { +                        if (!isalnum (temp_str[i]) && (temp_str[i] != '-')) { +                                ret = 0; +                                goto out; +                        } +                }          } -        if (flag) -                ret = 1;  out: +        if (dup_addr) +                GF_FREE (dup_addr);          return ret;  } +/*  Matches all ipv4 address, if wildcard_acc is true  '*' wildcard pattern for* +  subnets is considerd as valid strings as well                               */  char -valid_ipv4_address (char *address, int length) +valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc)  {          int octets = 0;          int value = 0;          char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL; -        char ret = 0; +        char ret = 1; +        int is_wildcard = 0;          tmp = gf_strdup (address);          prev = tmp; @@ -1634,15 +1666,22 @@ valid_ipv4_address (char *address, int length)          while (prev != NULL) {                  octets++; -                value = strtol (prev, &endptr, 10); -                if ((value > 255) || (value < 0) || -                    (endptr != NULL && *endptr != '\0')) -                        goto out; +                if (wildcard_acc && !strcmp (prev, "*")) { +                        is_wildcard = 1; +                } else { +                        value = strtol (prev, &endptr, 10); +                        if ((value > 255) || (value < 0) || +                            (endptr != NULL && *endptr != '\0')) { +                                ret = 0; +                                goto out; +                        } +                }                  prev = strtok_r (NULL, ".", &ptr);          } -        if (octets == 4) -                ret = 1; +        if ((octets > 4) || (octets < 4 && !is_wildcard)) { +                ret = 0; +        }  out:          GF_FREE (tmp); @@ -1650,27 +1689,35 @@ out:  }  char -valid_ipv6_address (char *address, int length) +valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc)  {          int hex_numbers = 0;          int value = 0;          char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL; -        char ret = 0; +        char ret = 1; +        int is_wildcard = 0;          tmp = gf_strdup (address);          prev = strtok_r (tmp, ":", &ptr);          while (prev != NULL) {                  hex_numbers++; -                value = strtol (prev, &endptr, 16); -                if ((value > 0xffff) || (value < 0) -                    || (endptr != NULL && *endptr != '\0')) -                        goto out; +                if (wildcard_acc && !strcmp (prev, "*")) { +                        is_wildcard = 1; +                } else { +                        value = strtol (prev, &endptr, 16); +                        if ((value > 0xffff) || (value < 0) +                        || (endptr != NULL && *endptr != '\0')) { +                                ret = 0; +                                goto out; +                        } +                }                  prev = strtok_r (NULL, ":", &ptr);          } -        if (hex_numbers <= 8) -                ret = 1; +        if ((hex_numbers > 8) || (hex_numbers < 8 && !is_wildcard)) { +                ret = 0; +        }  out:          GF_FREE (tmp); @@ -1678,7 +1725,7 @@ out:  }  char -valid_internet_address (char *address) +valid_internet_address (char *address, gf_boolean_t wildcard_acc)  {          char ret = 0;          int length = 0; @@ -1692,8 +1739,8 @@ valid_internet_address (char *address)          if (length == 0)                  goto out; -        if (valid_ipv4_address (address, length) -            || valid_ipv6_address (address, length) +        if (valid_ipv4_address (address, length, wildcard_acc) +            || valid_ipv6_address (address, length, wildcard_acc)              || valid_host_name (address, length))                  ret = 1; @@ -1701,104 +1748,6 @@ out:          return ret;  } -char -valid_ipv4_wildcard_check (char *address) -{ -        char    ret = 0; -        int     octets = 0; -        char    *tmp = NULL; -        char    *prev = NULL; -        char    *endptr = NULL; -        int     value = 0; -        int     is_wildcard = 0; - -        tmp = gf_strdup (address); -        prev = strtok (tmp, "."); - -        while (prev != NULL) { -                octets++; - -                if (!strcmp (prev, "*")) { -                        is_wildcard = 1; -                } else { -                        value = strtol (prev, &endptr, 10); - -                        if ((value > 255) || (value < 0) || -                            (endptr != NULL && *endptr != '\0')) -                                goto out; -                } -                prev = strtok (NULL, "."); -        } - -        if (is_wildcard && (octets <= 4)) -                ret = 1; - -out: -        if (tmp) -                GF_FREE (tmp); -        return ret; - -} - -char -valid_ipv6_wildcard_check (char *address) -{ -        char    ret = 0; -        int     hex_numbers = 0; -        int     value = 0; -        char    *tmp = NULL; -        char    *prev = NULL; -        char    *endptr = NULL; -        int     is_wildcard = 0; - -        tmp = gf_strdup (address); -        prev = strtok (tmp, ":"); - -        while (prev != NULL) { -                hex_numbers++; - -                if (!strcmp (prev, "*")) { -                        is_wildcard = 1; -                } else { -                        value = strtol (prev, &endptr, 16); - -                        if ((value > 0xffff) || (value < 0) || -                            (endptr != NULL && *endptr != '\0')) -                                goto out; -                } -                prev = strtok (NULL, ":"); -        } - -        if (is_wildcard && (hex_numbers <= 8)) -                ret = 1; -out: -        if (tmp) -                GF_FREE (tmp); -        return ret; -} - -char -valid_wildcard_internet_address (char *address) -{ -        char    ret = 0; - -        if (address == NULL) { -                gf_log_callingfn (THIS->name, GF_LOG_WARNING, -                                  "argument invalid"); -                goto out; -        } - -        if (strlen (address) == 0) -                goto out; - -        if (valid_ipv4_wildcard_check (address) || -            valid_ipv6_wildcard_check (address)) -                ret = 1; - -out: -        return ret; -} -  /*Thread safe conversion function*/  char *  uuid_utoa (uuid_t uuid) diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 8c9b26f7..33551779 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -465,9 +465,9 @@ void skip_word (char **str);  char *get_nth_word (const char *str, int n);  char valid_host_name (char *address, int length); -char valid_ipv4_address (char *address, int length); -char valid_ipv6_address (char *address, int length); -char valid_internet_address (char *address); +char valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc); +char valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc); +char valid_internet_address (char *address, gf_boolean_t wildcard_acc);  char valid_ipv4_wildcard_check (char *address);  char valid_ipv6_wildcard_check (char *address);  char valid_wildcard_internet_address (char *address); diff --git a/libglusterfs/src/options.c b/libglusterfs/src/options.c index 39844461..6da68fd9 100644 --- a/libglusterfs/src/options.c +++ b/libglusterfs/src/options.c @@ -464,10 +464,11 @@ xlator_option_validate_addr (xlator_t *xl, const char *key, const char *value,          int          ret = -1;          char         errstr[256]; -        if (!valid_internet_address ((char *)value)) { +        if (!valid_internet_address ((char *)value, _gf_false)) {                  snprintf (errstr, 256, -                          "internet address '%s' does not conform to standards.", -                          value); +                          "option %s %s: '%s'  is not a valid internet-address," +                          " it does not conform to standards.", +                          key, value, value);                  gf_log (xl->name, GF_LOG_ERROR, "%s", errstr);                  if (op_errstr)                          *op_errstr = gf_strdup (errstr); @@ -478,6 +479,176 @@ xlator_option_validate_addr (xlator_t *xl, const char *key, const char *value,          return ret;  } +static int +xlator_option_validate_addr_list (xlator_t *xl, const char *key, +                                  const char *value, volume_option_t *opt, +                                  char **op_errstr) +{ +        int          ret = -1; +        char         *dup_val = NULL; +        char         *addr_tok = NULL; +        char         *save_ptr = NULL; +        char         errstr[256]; + +        dup_val = gf_strdup (value); +        if (!dup_val) { +                ret = -1; +                snprintf (errstr, 256, "internal error, out of memory."); +                goto out; +        } + +        addr_tok = strtok_r (dup_val, ",", &save_ptr); +        while (addr_tok) { +                if (!valid_internet_address (addr_tok, _gf_true)) { +                        snprintf (errstr, 256, +                                  "option %s %s: '%s' is not a valid " +                                  "internet-address-list", +                                  key, value, value); +                        gf_log (xl->name, GF_LOG_ERROR, "%s", errstr); +                        ret = -1; +                        goto out; +                } +                addr_tok = strtok_r (NULL, ",", &save_ptr); +        } +        ret = 0; + out: +        if (op_errstr && ret) +                *op_errstr = gf_strdup (errstr); +        if (dup_val) +                GF_FREE (dup_val); + +        return ret; +} + +/*XXX: the rules to validate are as per block-size required for stripe xlator */ +static int +gf_validate_size (const char *sizestr, volume_option_t *opt) +{ +        uint64_t                value = 0; +        int                     ret = 0; + +        GF_ASSERT (opt); + +        if (gf_string2bytesize (sizestr, &value) != 0 || +            value < opt->min || +            value % 512) { +                ret = -1; +                goto out; +        } + + out: +        gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static int +gf_validate_number (const char *numstr, volume_option_t *opt) +{ +        int32_t value; +        return gf_string2int32 (numstr, &value); +} + +/*  Parses the string to be of the form <key1>:<value1>,<key2>:<value2>...  * + *  takes two optional validaters key_validator and value_validator         */ +static int +validate_list_elements (const char *string, volume_option_t *opt, +                        int (key_validator)( const char *), +                        int (value_validator)( const char *, volume_option_t *)) +{ + +        char                    *dup_string = NULL; +        char                    *str_sav = NULL; +        char                    *substr_sav = NULL; +        char                    *str_ptr = NULL; +        char                    *key = NULL; +        char                    *value = NULL; +        int                     ret = 0; + +        GF_ASSERT (string); + +        dup_string = gf_strdup (string); +        if (NULL == dup_string) +                goto out; + +        str_ptr = strtok_r (dup_string, ",", &str_sav); +        while (str_ptr) { + +                key = strtok_r (str_ptr, ":", &substr_sav); +                if (!key || +                    (key_validator && key_validator(key))) { +                        ret = -1; +                        gf_log (THIS->name, GF_LOG_WARNING, +                                "invalid list '%s', key '%s' not valid.", +                                string, key); +                        goto out; +                } + +                value = strtok_r (NULL, ":", &substr_sav); +                if (!value || +                    (value_validator && value_validator(value, opt))) { +                        ret = -1; +                        gf_log (THIS->name, GF_LOG_WARNING, +                                "invalid list '%s', value '%s' not valid.", +                                string, key); +                        goto out; +                } + +                str_ptr = strtok_r (NULL, ",", &str_sav); +                substr_sav = NULL; +        } + out: +        if (dup_string) +                GF_FREE (dup_string); +        gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret); +        return ret; +} + +static int +xlator_option_validate_priority_list (xlator_t *xl, const char *key, +                                      const char *value, volume_option_t *opt, +                                      char **op_errstr) +{ +        int                     ret =0; +        char                    errstr[1024] = {0, }; + +        GF_ASSERT (value); + +        ret = validate_list_elements (value, opt, NULL, &gf_validate_number); +        if (ret) { +                snprintf (errstr, 1024, +                          "option %s %s: '%s' is not a valid " +                          "priority-list", key, value, value); +                *op_errstr = gf_strdup (errstr); +        } + +        return ret; +} + +static int +xlator_option_validate_size_list (xlator_t *xl, const char *key, +                                  const char *value, volume_option_t *opt, +                                  char **op_errstr) +{ + +        int                    ret = 0; +        char                   errstr[1024] = {0, }; + +        GF_ASSERT (value); + +        ret = gf_validate_size (value, opt); +        if (ret) +                ret = validate_list_elements (value, opt, NULL, &gf_validate_size); + +        if (ret) { +                snprintf (errstr, 1024, +                          "option %s %s: '%s' is not a valid " +                          "size-list", key, value, value); +                *op_errstr = gf_strdup (errstr); +        } + +        return ret; + +}  static int  xlator_option_validate_any (xlator_t *xl, const char *key, const char *value, @@ -486,7 +657,6 @@ xlator_option_validate_any (xlator_t *xl, const char *key, const char *value,          return 0;  } -  typedef int (xlator_option_validator_t) (xlator_t *xl, const char *key,                                           const char *value,                                           volume_option_t *opt, char **operrstr); @@ -510,6 +680,11 @@ xlator_option_validate (xlator_t *xl, char *key, char *value,                  [GF_OPTION_TYPE_TIME]        = xlator_option_validate_time,                  [GF_OPTION_TYPE_DOUBLE]      = xlator_option_validate_double,                  [GF_OPTION_TYPE_INTERNET_ADDRESS] = xlator_option_validate_addr, +                [GF_OPTION_TYPE_INTERNET_ADDRESS_LIST] = +                xlator_option_validate_addr_list, +                [GF_OPTION_TYPE_PRIORITY_LIST] = +                xlator_option_validate_priority_list, +                [GF_OPTION_TYPE_SIZE_LIST]   = xlator_option_validate_size_list,                  [GF_OPTION_TYPE_ANY]         = xlator_option_validate_any,                  [GF_OPTION_TYPE_MAX]         = NULL,          }; diff --git a/libglusterfs/src/options.h b/libglusterfs/src/options.h index 40089ac6..722cc3b7 100644 --- a/libglusterfs/src/options.h +++ b/libglusterfs/src/options.h @@ -44,6 +44,9 @@ typedef enum {          GF_OPTION_TYPE_TIME,          GF_OPTION_TYPE_DOUBLE,          GF_OPTION_TYPE_INTERNET_ADDRESS, +        GF_OPTION_TYPE_INTERNET_ADDRESS_LIST, +        GF_OPTION_TYPE_PRIORITY_LIST, +        GF_OPTION_TYPE_SIZE_LIST,          GF_OPTION_TYPE_MAX,  } volume_option_type_t;  | 
