summaryrefslogtreecommitdiffstats
path: root/libglusterfs
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs')
-rw-r--r--libglusterfs/src/common-utils.c219
-rw-r--r--libglusterfs/src/common-utils.h6
-rw-r--r--libglusterfs/src/options.c183
-rw-r--r--libglusterfs/src/options.h3
4 files changed, 269 insertions, 142 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 952af10cfd0..f26d2bdc318 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 8c9b26f76d9..33551779974 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 39844461a65..6da68fd999a 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 40089ac6317..722cc3b7a5d 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;