+// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* This file is part of the PCEPlib, a PCEP protocol library.
*
* Copyright (C) 2020 Volta Networks https://voltanet.io/
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
* Author : Brady Johnson <brady@voltanet.io>
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <errno.h>
#include <stdio.h>
#include <string.h>
double_linked_list *pcep_msg_read(int sock_fd)
{
int ret;
- uint8_t buffer[PCEP_MAX_SIZE] = {0};
+ uint8_t buffer[PCEP_MESSAGE_LENGTH] = {0};
uint16_t buffer_read = 0;
- ret = read(sock_fd, &buffer, PCEP_MAX_SIZE);
+ ret = read(sock_fd, &buffer, PCEP_MESSAGE_LENGTH);
if (ret < 0) {
pcep_log(
double_linked_list *msg_list = dll_initialize();
struct pcep_message *msg = NULL;
- while ((ret - buffer_read) >= MESSAGE_HEADER_LENGTH) {
+ while (((uint16_t)ret - buffer_read) >= MESSAGE_HEADER_LENGTH) {
/* Get the Message header, validate it, and return the msg
* length */
- int32_t msg_hdr_length =
+ int32_t msg_length =
pcep_decode_validate_msg_header(buffer + buffer_read);
- if (msg_hdr_length < 0) {
+ if (msg_length < 0 || msg_length > PCEP_MESSAGE_LENGTH) {
/* If the message header is invalid, we cant keep
* reading since the length may be invalid */
pcep_log(
return msg_list;
}
- /* Check if the msg_hdr_length is longer than what was read,
+ /* Check if the msg_length is longer than what was read,
* in which case, we need to read the rest of the message. */
- if ((ret - buffer_read) < msg_hdr_length) {
- int read_len = (msg_hdr_length - (ret - buffer_read));
+ if ((ret - buffer_read) < msg_length) {
+ int read_len = (msg_length - (ret - buffer_read));
int read_ret = 0;
pcep_log(
LOG_INFO,
"%s: pcep_msg_read: Message not fully read! Trying to read %d bytes more, fd [%d]",
__func__, read_len, sock_fd);
- read_ret = read(sock_fd, &buffer[ret], read_len);
+ if (PCEP_MESSAGE_LENGTH - ret - buffer_read >= read_len)
+ read_ret =
+ read(sock_fd, &buffer[ret], read_len);
+ else {
+ pcep_log(
+ LOG_ERR,
+ "%s: Trying to read size (%d) offset (%d) in a buff of size (%d)",
+ __func__, read_len, ret,
+ PCEP_MESSAGE_LENGTH);
+ return msg_list;
+ }
if (read_ret != read_len) {
pcep_log(
}
msg = pcep_decode_message(buffer + buffer_read);
- buffer_read += msg_hdr_length;
+ buffer_read += msg_length;
if (msg == NULL) {
return msg_list;
}
break;
- default:
+ case PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR:
+ case PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST:
+ case PCEP_OBJ_TLV_TYPE_VENDOR_INFO:
+ case PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY:
+ case PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME:
+ case PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS:
+ case PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS:
+ case PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE:
+ case PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC:
+ case PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION:
+ case PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY:
+ case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE:
+ case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID:
+ case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME:
+ case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID:
+ case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE:
+ case PCEP_OBJ_TLV_TYPE_UNKNOWN:
+ case PCEP_OBJ_TYPE_CISCO_BSID:
+ case PCEP_OBJ_TLV_TYPE_ARBITRARY:
break;
}
}
break;
- default:
+ case PCEP_OBJ_CLASS_OPEN:
+ case PCEP_OBJ_CLASS_RP:
+ case PCEP_OBJ_CLASS_NOPATH:
+ case PCEP_OBJ_CLASS_ENDPOINTS:
+ case PCEP_OBJ_CLASS_BANDWIDTH:
+ case PCEP_OBJ_CLASS_METRIC:
+ case PCEP_OBJ_CLASS_LSPA:
+ case PCEP_OBJ_CLASS_NOTF:
+ case PCEP_OBJ_CLASS_ERROR:
+ case PCEP_OBJ_CLASS_CLOSE:
+ case PCEP_OBJ_CLASS_OF:
+ case PCEP_OBJ_CLASS_LSP:
+ case PCEP_OBJ_CLASS_SRP:
+ case PCEP_OBJ_CLASS_VENDOR_INFO:
+ case PCEP_OBJ_CLASS_INTER_LAYER:
+ case PCEP_OBJ_CLASS_REQ_ADAP_CAP:
+ case PCEP_OBJ_CLASS_SERVER_IND:
+ case PCEP_OBJ_CLASS_ASSOCIATION:
+ case PCEP_OBJ_CLASS_MAX:
break;
}
if (msg == NULL) {
return 0;
}
+ int msg_length = ntohs(msg->encoded_message_length);
+ if (msg_length > PCEP_MESSAGE_LENGTH) {
+ pcep_log(LOG_ERR, "%s: Not sended, size(% d) exceed max(% d) ",
+ __func__, msg_length, PCEP_MESSAGE_LENGTH);
+ return 0;
+ }
- return write(sock_fd, msg->encoded_message,
- ntohs(msg->encoded_message_length));
+ return write(sock_fd, msg->encoded_message, msg_length);
}