Skip to content
Snippets Groups Projects
Commit efbc7762 authored by Vladislav Shpilevoy's avatar Vladislav Shpilevoy Committed by Serge Petrenko
Browse files

box: introduce node_name funcs and constants

Node name stores a DNS- and host- friendly string name. It will be
used in the next patches for some new global names: cluster,
replicaset, and instance.

Part of #5029

NO_DOC=internal
NO_CHANGELOG=internal
parent ef86e000
No related branches found
No related tags found
No related merge requests found
...@@ -95,8 +95,10 @@ include_directories(${EXTRA_BOX_INCLUDE_DIRS}) ...@@ -95,8 +95,10 @@ include_directories(${EXTRA_BOX_INCLUDE_DIRS})
add_library(box_error STATIC error.cc errcode.c mp_error.cc) add_library(box_error STATIC error.cc errcode.c mp_error.cc)
target_link_libraries(box_error core stat mpstream vclock) target_link_libraries(box_error core stat mpstream vclock)
add_library(node_name STATIC node_name.c)
add_library(xrow STATIC xrow.c iproto_constants.c iproto_features.c) add_library(xrow STATIC xrow.c iproto_constants.c iproto_features.c)
target_link_libraries(xrow server core small vclock misc box_error target_link_libraries(xrow server core small vclock misc box_error node_name
${MSGPUCK_LIBRARIES}) ${MSGPUCK_LIBRARIES})
set(tuple_sources set(tuple_sources
...@@ -324,6 +326,6 @@ add_custom_command(OUTPUT ${SQL_BIN_DIR}/opcodes.c ...@@ -324,6 +326,6 @@ add_custom_command(OUTPUT ${SQL_BIN_DIR}/opcodes.c
${SQL_BIN_DIR}/opcodes.h) ${SQL_BIN_DIR}/opcodes.h)
target_link_libraries(box box_error tuple stat xrow xlog vclock crc32 raft target_link_libraries(box box_error tuple stat xrow xlog vclock crc32 raft
${common_libraries}) node_name ${common_libraries})
add_dependencies(box build_bundled_libs generate_sql_files) add_dependencies(box build_bundled_libs generate_sql_files)
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
*/
#include "node_name.h"
#include <ctype.h>
bool
node_name_is_valid_n(const char *name, size_t len)
{
if (len == 0 || len > NODE_NAME_LEN_MAX || !isalpha(*name))
return false;
const char *end = name + len;
while (name < end) {
char c = *(name++);
if (!isalnum(c) && c != '-')
return false;
if (tolower(c) != c)
return false;
}
return true;
}
/*
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright 2010-2023, Tarantool AUTHORS, please see AUTHORS file.
*/
#pragma once
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
/**
* Name suitable for a node visible in the network. Its format matches the
* sub-domain label in RFC 1035, section 2.3.1
* (https://www.rfc-editor.org/rfc/rfc1035#section-2.3.1).
*
* It allows to use the node name as a sub-domain and a host name.
*
* The limitations are: max 63 symbols (not including term 0); only lowercase
* letters, digits, and hyphen. Can start only with a letter. Note that the
* sub-domain name rules say that uppercase is allowed but the names are
* case-insensitive. In Tarantool the lowercase is enforced.
*/
enum {
NODE_NAME_LEN_MAX = 63,
NODE_NAME_SIZE_MAX = NODE_NAME_LEN_MAX + 1,
};
#if defined(__cplusplus)
extern "C" {
#endif /* defined(__cplusplus) */
/** Check if the node name of the given length is valid. */
bool
node_name_is_valid_n(const char *name, size_t len);
static inline bool
node_name_is_valid(const char *name)
{
return node_name_is_valid_n(name, strnlen(name, NODE_NAME_SIZE_MAX));
}
static inline const char *
node_name_str(const char *name)
{
if (name == NULL || *name == 0)
return "<no-name>";
return name;
}
#if defined(__cplusplus)
}
#endif /* defined(__cplusplus) */
...@@ -600,3 +600,8 @@ create_unit_test(PREFIX lua_tweaks ...@@ -600,3 +600,8 @@ create_unit_test(PREFIX lua_tweaks
${LIBYAML_LIBRARIES} ${LIBYAML_LIBRARIES}
${READLINE_LIBRARIES} ${READLINE_LIBRARIES}
) )
create_unit_test(PREFIX node_name
SOURCES node_name.c core_test_utils.c
LIBRARIES core unit node_name
)
#include "node_name.h"
#include "trivia/util.h"
#define UNIT_TAP_COMPATIBLE 1
#include "unit.h"
static void
test_node_name_is_valid(void)
{
header();
plan(27);
const char *bad_names[] = {
"",
"1",
"1abc",
"*",
"a_b",
"aBcD",
"a~b",
"{ab}",
};
for (int i = 0; i < (int)lengthof(bad_names); ++i) {
const char *str = bad_names[i];
ok(!node_name_is_valid(str), "bad name %d", i);
ok(!node_name_is_valid_n(str, strlen(str)),
"bad name n %d", i);
}
const char *good_names[] = {
"a",
"a-b-c",
"abc",
"a1b2c3-d4-e5-",
};
for (int i = 0; i < (int)lengthof(good_names); ++i) {
const char *str = good_names[i];
ok(node_name_is_valid(str), "bad name %d", i);
ok(node_name_is_valid_n(str, strlen(str)),
"bad name n %d", i);
}
char name[NODE_NAME_SIZE_MAX + 1];
memset(name, 'a', sizeof(name));
ok(!node_name_is_valid_n(name, NODE_NAME_SIZE_MAX), "max + 1");
ok(node_name_is_valid_n(name, NODE_NAME_LEN_MAX), "max n");
name[NODE_NAME_SIZE_MAX - 1] = 0;
ok(node_name_is_valid(name), "max");
check_plan();
footer();
}
static void
test_node_name_str(void)
{
header();
plan(3);
const char *stub = "<no-name>";
is(strcmp(node_name_str("abc"), "abc"), 0, "name");
is(strcmp(node_name_str(""), stub), 0, "empty");
is(strcmp(node_name_str(NULL), stub), 0, "null");
check_plan();
footer();
}
int
main(void)
{
header();
plan(2);
test_node_name_is_valid();
test_node_name_str();
int rc = check_plan();
footer();
return rc;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment