LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/sandesh/library/c - sandesh.c (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 48 92 52.2 %
Date: 2026-08-03 02:19:58 Functions: 4 5 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : /*
       6             :  * sandesh.c
       7             :  *
       8             :  * Sandesh C Library
       9             :  */
      10             : 
      11             : #include "sandesh.h"
      12             : 
      13             : /**
      14             :  * Extract sandesh information corresponding to sandesh name
      15             :  *
      16             :  * Returns sandesh info on success, NULL otherwise
      17             :  */
      18             : sandesh_info_t *
      19       13872 : sandesh_find_info (sandesh_info_t *infos, const char *name) {
      20       13872 :     int sidx = 0;
      21      104676 :     while (infos[sidx].name != NULL) {
      22      104676 :         if (strcmp(infos[sidx].name, name) == 0) {
      23       13872 :             return &infos[sidx];
      24             :         }
      25       90804 :         sidx++;
      26             :     }
      27           0 :     return NULL;
      28             : }
      29             : 
      30             : /**
      31             :  * Decode a sandesh from the buffer and call the sandesh handler function
      32             :  *
      33             :  * Returns the number of bytes processed, -1 on error and sets error
      34             :  */
      35             : static int32_t
      36        6593 : sandesh_decode_one (u_int8_t *buf, u_int32_t buf_len, sandesh_find_info_fn sinfo_find_fn,
      37             :                     int *error) {
      38        6593 :     int32_t rxfer = 0, ret, sread_len = 0;
      39        6593 :     char *sname = NULL;
      40             :     sandesh_info_t *sinfo;
      41             :     void *sandesh;
      42             :     union {
      43             :         void * b[4];
      44             :         int32_t all;
      45             :     } bytes4;
      46             : 
      47             :     /* Read the sandesh name */
      48        6593 :     if (buf_len < (uint32_t)(rxfer + 4)) {
      49           0 :         os_log(OS_LOG_ERR, "Read sandesh begin FAILED");
      50           0 :         ret = -1;
      51           0 :         goto exit;
      52             :     }
      53        6593 :     memcpy(bytes4.b, buf + rxfer, 4);
      54        6593 :     rxfer += 4;
      55        6593 :     sread_len = ntohl(bytes4.all);
      56        6593 :     if (sread_len > 0) {
      57        6593 :         if (buf_len < (uint32_t)(rxfer + sread_len)) {
      58           0 :             os_log(OS_LOG_ERR, "Read sandesh begin: Length(%d) FAILED",
      59             :                 sread_len);
      60           0 :             ret = -1;
      61           0 :             goto exit;
      62             :         }
      63        6593 :         sname = os_malloc(sread_len + 1);
      64        6593 :         memcpy(sname, buf + rxfer, sread_len);
      65        6593 :         sname[sread_len] = 0;
      66        6593 :         rxfer += sread_len;
      67             :     } else {
      68           0 :         os_log(OS_LOG_ERR, "Read sandesh begin: Length(%d) INVALID",
      69             :             sread_len);
      70           0 :         ret = -1;
      71           0 :         goto exit;
      72             :     }
      73             : 
      74             :     /* Find the corresponding sandesh information */
      75        6593 :     sinfo = sinfo_find_fn(sname);
      76        6593 :     if (sinfo == NULL) {
      77           0 :         os_log(OS_LOG_ERR, "No information for sandesh %s", sname);
      78           0 :         *error = EINVAL;
      79           0 :         ret = -1;
      80           0 :         goto exit;
      81             :     }
      82             : 
      83        6593 :     sandesh = os_zalloc(sinfo->size);
      84        6593 :     if (sandesh == NULL) {
      85           0 :         os_log(OS_LOG_ERR, "Allocation of sandesh %s : %d bytes FAILED",
      86             :                sname, sinfo->size);
      87           0 :         *error = ENOMEM;
      88           0 :         ret = -1;
      89           0 :         goto exit;
      90             :     }
      91             : 
      92             :     /* Now, read the sandesh */
      93        6593 :     rxfer = sinfo->read_binary_from_buffer(sandesh, buf, buf_len, error);
      94        6593 :     if (rxfer < 0) {
      95           0 :         os_log(OS_LOG_ERR, "%s read FAILED (%d)", sname, *error);
      96           0 :         sinfo->free(sandesh);
      97           0 :         os_free(sandesh);
      98           0 :         sandesh = NULL;
      99           0 :         ret = -1;
     100           0 :         goto exit;
     101             :     }
     102        6593 :     ret = rxfer;
     103             : 
     104             :     /* Process the sandesh */
     105        6593 :     sinfo->process(sandesh);
     106             : 
     107             :     /* Release the sandesh */
     108        6593 :     sinfo->free(sandesh);
     109        6593 :     os_free(sandesh);
     110        6593 :     sandesh = NULL;
     111             : 
     112        6593 : exit:
     113        6593 :     if (sname) {
     114        6593 :         os_free(sname);
     115        6593 :         sname = NULL;
     116             :     }
     117        6593 :     return ret;
     118             : }
     119             : 
     120             : /**
     121             :  * Decode sandeshs from the buffer and calls the sandesh handler function
     122             :  * for each decoded sandesh
     123             :  *
     124             :  * Returns the number of bytes processed, -1 on error and sets error
     125             :  */
     126             : int32_t
     127        5725 : sandesh_decode (u_int8_t *buf, u_int32_t buf_len, sandesh_find_info_fn sinfo_find_fn,
     128             :                 int *error) {
     129        5725 :     u_int32_t xfer = 0;
     130             :     int32_t ret;
     131             : 
     132       12318 :     while (xfer < buf_len) {
     133        6593 :         ret = sandesh_decode_one(buf + xfer, buf_len - xfer, sinfo_find_fn, error);
     134        6593 :         if (ret < 0) {
     135           0 :             os_log(OS_LOG_ERR, "Sandesh read from %d bytes, at offset %d "
     136             :                     "FAILED (%d)", buf_len, xfer, ret);
     137           0 :             return ret;
     138             :         }
     139        6593 :         xfer += ret;
     140             :     }
     141        5725 :     return xfer;
     142             : }
     143             : 
     144             : /*
     145             :  * Encode a sandesh into the buffer
     146             :  *
     147             :  * Returns the length of the encoded sandesh, -1 on error and set error
     148             :  */
     149             : int32_t
     150        6593 : sandesh_encode (void *sandesh, const char *sname,
     151             :                 sandesh_find_info_fn sinfo_find_fn, u_int8_t *buf,
     152             :                 u_int32_t buf_len, int *error) {
     153             :     sandesh_info_t *sinfo;
     154             :     int32_t wxfer;
     155             : 
     156             :     /* First find the corresponding sandesh information */
     157        6593 :     sinfo = sinfo_find_fn(sname);
     158        6593 :     if (sinfo == NULL) {
     159           0 :         os_log(OS_LOG_ERR, "Write: No information for sandesh %s", sname);
     160           0 :         *error = EINVAL;
     161           0 :         return -1;
     162             :     }
     163             : 
     164             :     /* Now, write the sandesh */
     165        6593 :     wxfer = sinfo->write_binary_to_buffer(sandesh, buf, buf_len, error);
     166        6593 :     if (wxfer < 0) {
     167             : #ifdef __KERNEL__
     168             :         if (vrouter_dbg) {
     169             :             os_log(OS_LOG_DEBUG, "Write: Encode sandesh %s FAILED(%d)",
     170             :                    sname, *error);
     171             :         }
     172             : #elif (!defined(SANDESH_QUIET))
     173           0 :         os_log(OS_LOG_DEBUG, "Write: Encode sandesh %s FAILED(%d)", sname, *error);
     174             : #endif
     175           0 :         return -1;
     176             :     }
     177             : 
     178        6593 :     return wxfer;
     179             : }
     180             : 
     181             : /*
     182             :  * Get the encoded length of a sandesh
     183             :  *
     184             :  * Returns the encoded length of a sandesh, -1 on error and set error
     185             :  */
     186             : int32_t
     187           0 : sandesh_get_encoded_length (void *sandesh, const char *sname,
     188             :                             sandesh_find_info_fn sinfo_find_fn, int *error) {
     189             :     ThriftBinaryProtocol protocol;
     190             :     ThriftFakeTransport transport;
     191             :     sandesh_info_t *sinfo;
     192             :     int32_t wxfer;
     193             : 
     194             :     /* First find the corresponding sandesh information */
     195           0 :     sinfo = sinfo_find_fn(sname);
     196           0 :     if (sinfo == NULL) {
     197           0 :         os_log(OS_LOG_ERR, "Encode: No information for sandesh %s", sname);
     198           0 :         *error = EINVAL;
     199           0 :         return -1;
     200             :     }
     201             : 
     202             :     /* Initialize the transport and protocol */
     203           0 :     thrift_fake_transport_init(&transport);
     204           0 :     thrift_protocol_init(&protocol, T_PROTOCOL_BINARY, (ThriftTransport *)&transport);
     205             : 
     206             :     /* Now, write the sandesh into the fake transport to get the encoded length */
     207           0 :     wxfer = sinfo->write(sandesh, &protocol, error);
     208           0 :     if (wxfer < 0) {
     209           0 :         os_log(OS_LOG_ERR, "Encode: Encode sandesh %s FAILED(%d)", sname, *error);
     210           0 :         return -1;
     211             :     }
     212             : 
     213           0 :     return wxfer;
     214             : }

Generated by: LCOV version 1.14