mirror of
https://gitlab.com/d3tn/ud3tn.git
synced 2026-08-13 12:33:27 +02:00
Add command-line options for cppcheck to the CI job: - `--suppress=constParameterCallback` - `--check-level=exhaustive` information: Limiting analysis of branches. Use --check-level=exhaustive to analyze all branches. - `--force` information: Too many #ifdef configurations - cppcheck only checks 12 configurations. Use --force to check all configurations. Signed-off-by: Maximilian Nitsch <maximilian.nitsch@d3tn.com>
553 lines
17 KiB
C
553 lines
17 KiB
C
// SPDX-License-Identifier: BSD-3-Clause OR Apache-2.0
|
|
#include "routing/compat/config_parser.h"
|
|
#include "routing/compat/node.h"
|
|
#include "routing/compat/router.h"
|
|
|
|
#include "platform/hal_io.h"
|
|
|
|
#include "ud3tn/eid.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
|
|
static const char EID_START_DELIMITER = '(';
|
|
static const char EID_END_DELIMITER = ')';
|
|
static const char CLA_ADDR_START_DELIMITER = '(';
|
|
static const char CLA_ADDR_END_DELIMITER = ')';
|
|
static const char NODE_CONF_RELIABILITY_SEPARATOR = ',';
|
|
static const char NODE_CONF_CLA_ADDR_SEPARATOR = ':';
|
|
static const char CLA_ADDR_NODES_SEPARATOR = ':';
|
|
static const char LIST_START_DELIMITER = '[';
|
|
static const char LIST_END_DELIMITER = ']';
|
|
static const char LIST_ELEMENT_SEPARATOR = ',';
|
|
static const char OBJECT_START_DELIMITER = '{';
|
|
static const char OBJECT_END_DELIMITER = '}';
|
|
static const char OBJECT_ELEMENT_SEPARATOR = ',';
|
|
static const char NODES_CONTACTS_SEPARATOR = ':';
|
|
|
|
static const uint8_t COMMAND_END_MARKER = ';';
|
|
|
|
static const uint8_t DEFAULT_EID_BUFFER_SIZE = 16;
|
|
static const uint8_t DEFAULT_CLA_ADDR_BUFFER_SIZE = 21;
|
|
static const uint8_t DEFAULT_INT_BUFFER_SIZE = 16;
|
|
|
|
static void begin_read_data_eid(
|
|
struct config_parser *parser, struct endpoint_list **target)
|
|
{
|
|
struct endpoint_list *new_entry = malloc(sizeof(struct endpoint_list));
|
|
|
|
if (!new_entry)
|
|
return;
|
|
|
|
char *new_eid = malloc(DEFAULT_EID_BUFFER_SIZE * sizeof(char));
|
|
|
|
if (!new_eid) {
|
|
free(new_entry);
|
|
return;
|
|
}
|
|
|
|
new_eid[0] = '\0';
|
|
new_entry->eid = new_eid;
|
|
new_entry->next = NULL;
|
|
|
|
if (parser->current_eid == NULL)
|
|
*target = new_entry;
|
|
else
|
|
parser->current_eid->next = new_entry;
|
|
parser->current_eid = new_entry;
|
|
parser->current_index = 0;
|
|
}
|
|
|
|
static void begin_read_node_conf_eid(struct config_parser *parser)
|
|
{
|
|
parser->router_command->data->eid =
|
|
malloc(DEFAULT_EID_BUFFER_SIZE * sizeof(char));
|
|
parser->router_command->data->eid[0] = '\0';
|
|
parser->current_index = 0;
|
|
}
|
|
|
|
static bool read_eid(
|
|
struct config_parser *parser, char **eid_ptr, const char byte)
|
|
{
|
|
/* Check for valid chars (URIs) */
|
|
if (
|
|
/* !"#$%&'()*+,-./0123456789:<=>?@ / A-Z / [\]^_ */
|
|
(byte >= 0x21 && byte <= 0x5F) ||
|
|
/* a-z / ~ */
|
|
(byte >= 0x61 && byte <= 0x7A) || byte == 0x7E
|
|
) {
|
|
(*eid_ptr)[parser->current_index++] = byte;
|
|
if (parser->current_index >= DEFAULT_EID_BUFFER_SIZE)
|
|
(*eid_ptr) = realloc(*eid_ptr,
|
|
(parser->current_index + 1) * sizeof(char));
|
|
(*eid_ptr)[parser->current_index] = '\0';
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static void end_read_eid(const struct config_parser *parser, char **eid_ptr)
|
|
{
|
|
(*eid_ptr)[parser->current_index] = '\0';
|
|
|
|
struct eid read_eid_struct = eid_from_string(*eid_ptr);
|
|
// Our current router implementation searches for the EID returned by
|
|
// get_node_id(destination). This might differ, e.g., by a slash added
|
|
// at the end of a `dtn` scheme EID. Thus, we want to ensure that this
|
|
// value is added to the routing table if we can determine it.
|
|
struct eid node_id = eid_get_admin_endpoint(read_eid_struct);
|
|
char *const node_id_str = eid_to_string(node_id);
|
|
|
|
eid_free(read_eid_struct);
|
|
eid_free(node_id);
|
|
|
|
if (node_id_str) {
|
|
free(*eid_ptr);
|
|
*eid_ptr = node_id_str;
|
|
}
|
|
}
|
|
|
|
static void begin_read_cla_addr(struct config_parser *parser)
|
|
{
|
|
parser->router_command->data->cla_addr =
|
|
malloc(DEFAULT_CLA_ADDR_BUFFER_SIZE * sizeof(char));
|
|
parser->router_command->data->cla_addr[0] = '\0';
|
|
parser->current_index = 0;
|
|
}
|
|
|
|
static void end_read_cla_addr(
|
|
const struct config_parser *parser, char **cla_addr_ptr)
|
|
{
|
|
(*cla_addr_ptr)[parser->current_index] = '\0';
|
|
}
|
|
|
|
static bool read_cla_addr(
|
|
struct config_parser *parser, char **cla_addr_ptr, const char byte)
|
|
{
|
|
if (
|
|
(byte >= '0' && byte <= '9') ||
|
|
(byte >= 'A' && byte <= 'Z') ||
|
|
(byte >= 'a' && byte <= 'z') ||
|
|
(byte == ':') || (byte == '.') ||
|
|
(byte == '[') || (byte == ']') ||
|
|
(byte == '#') || (byte == '/') ||
|
|
(byte == '-')
|
|
) {
|
|
(*cla_addr_ptr)[parser->current_index++] = byte;
|
|
if (parser->current_index >= DEFAULT_CLA_ADDR_BUFFER_SIZE)
|
|
(*cla_addr_ptr) = realloc(*cla_addr_ptr,
|
|
(parser->current_index + 1) * sizeof(char));
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static void begin_read_contact(struct config_parser *parser)
|
|
{
|
|
struct contact_list *new_entry = malloc(sizeof(struct contact_list));
|
|
|
|
if (!new_entry)
|
|
return;
|
|
|
|
new_entry->next = NULL;
|
|
new_entry->data = contact_create(parser->router_command->data);
|
|
if (parser->current_contact == NULL)
|
|
parser->router_command->data->contacts = new_entry;
|
|
else
|
|
parser->current_contact->next = new_entry;
|
|
parser->current_contact = new_entry;
|
|
/* Reset for contact eids, misc eid reading has finished here */
|
|
parser->current_eid = NULL;
|
|
}
|
|
|
|
static void begin_read_integer(struct config_parser *parser)
|
|
{
|
|
parser->current_int_data =
|
|
malloc(DEFAULT_INT_BUFFER_SIZE * sizeof(char));
|
|
parser->current_index = 0;
|
|
}
|
|
|
|
static bool read_integer(struct config_parser *parser, const char byte)
|
|
{
|
|
if (byte >= 0x30 && byte <= 0x39) { /* 0..9 */
|
|
parser->current_int_data[parser->current_index++] = byte;
|
|
if (parser->current_index >= DEFAULT_INT_BUFFER_SIZE)
|
|
parser->current_int_data = realloc(
|
|
parser->current_int_data,
|
|
(parser->current_index + 1) * sizeof(char));
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static void end_read_uint64(struct config_parser *parser, uint64_t *out)
|
|
{
|
|
parser->current_int_data[parser->current_index] = '\0';
|
|
/* No further checks because read_integer already checks for digits */
|
|
*out = strtoull(parser->current_int_data, NULL, 10);
|
|
free(parser->current_int_data);
|
|
parser->current_int_data = NULL;
|
|
}
|
|
|
|
static void end_read_uint32(struct config_parser *parser, uint32_t *out)
|
|
{
|
|
parser->current_int_data[parser->current_index] = '\0';
|
|
/* No further checks because read_integer already checks for digits */
|
|
*out = strtoul(parser->current_int_data, NULL, 10);
|
|
free(parser->current_int_data);
|
|
parser->current_int_data = NULL;
|
|
}
|
|
|
|
static void end_read_uint16(struct config_parser *parser, uint16_t *out)
|
|
{
|
|
parser->current_int_data[parser->current_index] = '\0';
|
|
/* No further checks because read_integer already checks for digits */
|
|
/* XXX: Overflow might be possible here */
|
|
*out = (uint16_t)atoi(parser->current_int_data);
|
|
free(parser->current_int_data);
|
|
parser->current_int_data = NULL;
|
|
}
|
|
|
|
static void read_command(struct config_parser *parser, const uint8_t byte)
|
|
{
|
|
uint16_t tmp;
|
|
struct node *cur_gs = parser->router_command->data;
|
|
|
|
switch (parser->stage) {
|
|
default:
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_NODE_CONF_START_DELIMITER:
|
|
if (byte == EID_START_DELIMITER) {
|
|
begin_read_node_conf_eid(parser);
|
|
parser->stage = RP_EXPECT_NODE_CONF_EID;
|
|
} else {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_NODE_CONF_EID:
|
|
if (byte == EID_END_DELIMITER) {
|
|
end_read_eid(parser, &(cur_gs->eid));
|
|
parser->stage =
|
|
RP_EXPECT_NODE_CONF_RELIABILITY_SEPARATOR;
|
|
} else if (!read_eid(parser, &(cur_gs->eid), byte)) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_NODE_CONF_RELIABILITY_SEPARATOR:
|
|
if (byte == NODE_CONF_RELIABILITY_SEPARATOR) {
|
|
begin_read_integer(parser);
|
|
parser->stage = RP_EXPECT_NODE_CONF_RELIABILITY;
|
|
} else if (byte == NODE_CONF_CLA_ADDR_SEPARATOR) {
|
|
parser->stage = RP_EXPECT_CLA_ADDR_START_DELIMITER;
|
|
} else if (byte == COMMAND_END_MARKER) {
|
|
parser->basedata->status = PARSER_STATUS_DONE;
|
|
} else {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_NODE_CONF_RELIABILITY:
|
|
if (byte == NODE_CONF_CLA_ADDR_SEPARATOR ||
|
|
byte == COMMAND_END_MARKER
|
|
) {
|
|
end_read_uint16(parser, &tmp);
|
|
if (tmp < 100 || tmp > 1000) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
}
|
|
// NOTE: Reliability is not used anymore.
|
|
parser->stage = RP_EXPECT_CLA_ADDR_START_DELIMITER;
|
|
if (byte == COMMAND_END_MARKER)
|
|
parser->basedata->status = PARSER_STATUS_DONE;
|
|
} else if (!read_integer(parser, byte)) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_CLA_ADDR_START_DELIMITER:
|
|
if (byte == CLA_ADDR_START_DELIMITER) {
|
|
begin_read_cla_addr(parser);
|
|
parser->stage = RP_EXPECT_CLA_ADDR;
|
|
} else if (byte == CLA_ADDR_NODES_SEPARATOR) {
|
|
parser->stage = RP_EXPECT_NODE_LIST_START_DELIMITER;
|
|
} else if (byte == COMMAND_END_MARKER) {
|
|
parser->basedata->status = PARSER_STATUS_DONE;
|
|
} else {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_CLA_ADDR:
|
|
if (byte == CLA_ADDR_END_DELIMITER) {
|
|
end_read_cla_addr(parser, &(cur_gs->cla_addr));
|
|
parser->stage = RP_EXPECT_CLA_ADDR_NODES_SEPARATOR;
|
|
} else if (!read_cla_addr(parser, &(cur_gs->cla_addr), byte)) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_CLA_ADDR_NODES_SEPARATOR:
|
|
if (byte == CLA_ADDR_NODES_SEPARATOR)
|
|
parser->stage = RP_EXPECT_NODE_LIST_START_DELIMITER;
|
|
else if (byte == COMMAND_END_MARKER)
|
|
parser->basedata->status = PARSER_STATUS_DONE;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_NODE_LIST_START_DELIMITER:
|
|
if (byte == LIST_START_DELIMITER)
|
|
parser->stage = RP_EXPECT_NODE_START_DELIMITER;
|
|
else if (byte == NODES_CONTACTS_SEPARATOR)
|
|
parser->stage = RP_EXPECT_CONTACT_LIST_START_DELIMITER;
|
|
else if (byte == COMMAND_END_MARKER)
|
|
parser->basedata->status = PARSER_STATUS_DONE;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_NODE_START_DELIMITER:
|
|
if (byte == EID_START_DELIMITER) {
|
|
begin_read_data_eid(parser, &(cur_gs->endpoints));
|
|
parser->stage = RP_EXPECT_NODE_EID;
|
|
} else if (byte == LIST_END_DELIMITER) {
|
|
parser->stage = RP_EXPECT_NODES_CONTACTS_SEPARATOR;
|
|
} else {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_NODE_EID:
|
|
if (byte == EID_END_DELIMITER) {
|
|
end_read_eid(parser,
|
|
&(parser->current_eid->eid));
|
|
parser->stage = RP_EXPECT_NODE_SEPARATOR;
|
|
} else if (!read_eid(parser,
|
|
&(parser->current_eid->eid), byte)
|
|
) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_NODE_SEPARATOR:
|
|
if (byte == LIST_ELEMENT_SEPARATOR)
|
|
parser->stage = RP_EXPECT_NODE_START_DELIMITER;
|
|
else if (byte == LIST_END_DELIMITER)
|
|
parser->stage = RP_EXPECT_NODES_CONTACTS_SEPARATOR;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_NODES_CONTACTS_SEPARATOR:
|
|
if (byte == NODES_CONTACTS_SEPARATOR)
|
|
parser->stage = RP_EXPECT_CONTACT_LIST_START_DELIMITER;
|
|
else if (byte == COMMAND_END_MARKER)
|
|
parser->basedata->status = PARSER_STATUS_DONE;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_CONTACT_LIST_START_DELIMITER:
|
|
if (byte == LIST_START_DELIMITER)
|
|
parser->stage = RP_EXPECT_CONTACT_START_DELIMITER;
|
|
else if (byte == COMMAND_END_MARKER)
|
|
parser->basedata->status = PARSER_STATUS_DONE;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_CONTACT_START_DELIMITER:
|
|
if (byte == OBJECT_START_DELIMITER) {
|
|
begin_read_contact(parser);
|
|
begin_read_integer(parser);
|
|
parser->stage = RP_EXPECT_CONTACT_START_TIME;
|
|
} else if (byte == LIST_END_DELIMITER) {
|
|
parser->stage = RP_EXPECT_COMMAND_END_MARKER;
|
|
} else {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_CONTACT_START_TIME:
|
|
if (byte == OBJECT_ELEMENT_SEPARATOR) {
|
|
end_read_uint64(parser,
|
|
&(parser->current_contact->data->from_ms));
|
|
if (parser->current_contact->data->from_ms >=
|
|
UINT64_MAX / 1000) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
}
|
|
parser->current_contact->data->from_ms *= 1000;
|
|
begin_read_integer(parser);
|
|
parser->stage = RP_EXPECT_CONTACT_END_TIME;
|
|
} else if (!read_integer(parser, byte)) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_CONTACT_END_TIME:
|
|
if (byte == OBJECT_ELEMENT_SEPARATOR) {
|
|
end_read_uint64(parser,
|
|
&(parser->current_contact->data->to_ms));
|
|
if (parser->current_contact->data->to_ms >=
|
|
UINT64_MAX / 1000) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
}
|
|
parser->current_contact->data->to_ms *= 1000;
|
|
begin_read_integer(parser);
|
|
parser->stage = RP_EXPECT_CONTACT_BITRATE;
|
|
} else if (!read_integer(parser, byte)) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_CONTACT_BITRATE:
|
|
if (byte == OBJECT_ELEMENT_SEPARATOR) {
|
|
end_read_uint32(parser, &(parser->current_contact->data
|
|
->bitrate_bytes_per_s));
|
|
parser->stage =
|
|
RP_EXPECT_CONTACT_NODE_LIST_START_DELIMITER;
|
|
} else if (byte == OBJECT_END_DELIMITER) {
|
|
end_read_uint32(parser, &(parser->current_contact->data
|
|
->bitrate_bytes_per_s));
|
|
parser->stage = RP_EXPECT_CONTACT_SEPARATOR;
|
|
} else if (!read_integer(parser, byte)) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_CONTACT_NODE_LIST_START_DELIMITER:
|
|
if (byte == LIST_START_DELIMITER)
|
|
parser->stage = RP_EXPECT_CONTACT_NODE_START_DELIMITER;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_CONTACT_NODE_START_DELIMITER:
|
|
if (byte == EID_START_DELIMITER) {
|
|
begin_read_data_eid(parser, &(parser->current_contact
|
|
->data->contact_endpoints));
|
|
parser->stage = RP_EXPECT_CONTACT_NODE_EID;
|
|
} else if (byte == LIST_END_DELIMITER) {
|
|
parser->stage = RP_EXPECT_CONTACT_END_DELIMITER;
|
|
} else {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_CONTACT_NODE_EID:
|
|
if (byte == EID_END_DELIMITER) {
|
|
end_read_eid(parser, &(parser->current_eid->eid));
|
|
parser->stage = RP_EXPECT_CONTACT_NODE_SEPARATOR;
|
|
} else if (!read_eid(parser,
|
|
&(parser->current_eid->eid), byte)
|
|
) {
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
}
|
|
break;
|
|
case RP_EXPECT_CONTACT_NODE_SEPARATOR:
|
|
if (byte == LIST_ELEMENT_SEPARATOR)
|
|
parser->stage = RP_EXPECT_CONTACT_NODE_START_DELIMITER;
|
|
else if (byte == LIST_END_DELIMITER)
|
|
parser->stage = RP_EXPECT_CONTACT_END_DELIMITER;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_CONTACT_END_DELIMITER:
|
|
if (byte == OBJECT_END_DELIMITER)
|
|
parser->stage = RP_EXPECT_CONTACT_SEPARATOR;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_CONTACT_SEPARATOR:
|
|
if (byte == LIST_ELEMENT_SEPARATOR)
|
|
parser->stage = RP_EXPECT_CONTACT_START_DELIMITER;
|
|
else if (byte == LIST_END_DELIMITER)
|
|
parser->stage = RP_EXPECT_COMMAND_END_MARKER;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
case RP_EXPECT_COMMAND_END_MARKER:
|
|
if (byte == COMMAND_END_MARKER)
|
|
parser->basedata->status = PARSER_STATUS_DONE;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void config_parser_read_byte(struct config_parser *parser, uint8_t byte)
|
|
{
|
|
if (parser->basedata->status != PARSER_STATUS_GOOD)
|
|
return;
|
|
|
|
if (parser->stage == RP_EXPECT_COMMAND_TYPE) {
|
|
parser->stage = RP_EXPECT_NODE_CONF_START_DELIMITER;
|
|
if (byte >= (uint8_t)ROUTER_COMMAND_ADD &&
|
|
byte <= (uint8_t)ROUTER_COMMAND_QUERY)
|
|
parser->router_command->type = (enum router_command_type)byte;
|
|
else
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
} else {
|
|
read_command(parser, *(char *)(&byte));
|
|
}
|
|
}
|
|
|
|
size_t config_parser_read(struct config_parser *parser,
|
|
const uint8_t *buffer, size_t length)
|
|
{
|
|
size_t i = 0;
|
|
|
|
while (i < length) {
|
|
if (parser->basedata->status != PARSER_STATUS_GOOD &&
|
|
parser->basedata->status != PARSER_STATUS_DONE) {
|
|
LOGF_WARN(
|
|
"ConfigAgentParser: parser status was not good at %d ('%c') -> reset parser",
|
|
i,
|
|
buffer[i]
|
|
);
|
|
config_parser_reset(parser);
|
|
return length;
|
|
}
|
|
config_parser_read_byte(parser, buffer[i]);
|
|
i++;
|
|
if (parser->basedata->status == PARSER_STATUS_DONE)
|
|
break;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
enum ud3tn_result config_parser_reset(struct config_parser *parser)
|
|
{
|
|
if (parser->basedata->status == PARSER_STATUS_GOOD &&
|
|
parser->stage == RP_EXPECT_COMMAND_TYPE)
|
|
return UD3TN_OK;
|
|
else if (parser->basedata->status == PARSER_STATUS_ERROR)
|
|
(void)parser;
|
|
parser->basedata->status = PARSER_STATUS_GOOD;
|
|
parser->basedata->flags = PARSER_FLAG_NONE;
|
|
parser->stage = RP_EXPECT_COMMAND_TYPE;
|
|
parser->current_eid = NULL;
|
|
parser->current_contact = NULL;
|
|
if (parser->router_command != NULL) {
|
|
if (parser->router_command->data != NULL)
|
|
free_node(parser->router_command->data);
|
|
free(parser->router_command);
|
|
parser->router_command = NULL;
|
|
}
|
|
if (parser->current_int_data != NULL) {
|
|
free(parser->current_int_data);
|
|
parser->current_int_data = NULL;
|
|
}
|
|
parser->router_command = malloc(sizeof(struct router_command));
|
|
if (parser->router_command == NULL)
|
|
return UD3TN_FAIL;
|
|
parser->router_command->type = ROUTER_COMMAND_UNDEFINED;
|
|
parser->router_command->data = node_create(NULL);
|
|
if (parser->router_command->data == NULL)
|
|
return UD3TN_FAIL;
|
|
return UD3TN_OK;
|
|
}
|
|
|
|
struct parser *config_parser_init(struct config_parser *parser)
|
|
{
|
|
parser->basedata = malloc(sizeof(struct parser));
|
|
if (parser->basedata == NULL)
|
|
return NULL;
|
|
parser->basedata->status = PARSER_STATUS_ERROR;
|
|
parser->router_command = NULL;
|
|
if (config_parser_reset(parser) != UD3TN_OK)
|
|
return NULL;
|
|
return parser->basedata;
|
|
}
|