<commit_before>/*
 * Core implementation of normal uipcps.
 *
 * Copyright (C) 2015-2016 Nextworks
 * Author: <NAME> <<EMAIL>>
 *
 * This file is part of rlite.
 *
 * 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.1 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 library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <vector>
#include <list>
#include <map>
#include <string>
#include <iostream>
#include <fstream>
#include <cstring>
#include <sstream>
#include <unistd.h>
#include <stdint.h>
#include <cstdlib>
#include <cassert>
#include <cerrno>
#include <pthread.h>
#include <poll.h>

#include <rlite/conf.h>

#include "uipcp-normal.hpp"

using namespace std;


namespace obj_class {
    string adata = "a_data";
    string dft = "dft";
    string neighbors = "neighbors";
    string enrollment = "enrollment";
    string status = "operational_status";
    string address = "address";
    string lfdb = "fsodb"; /* Lower Flow DB */
    string flows = "flows"; /* Supported flows */
    string flow = "flow";
    string keepalive = "keepalive";
    string lowerflow = "lowerflow";
    string addr_alloc_table = "addr_alloc_table";
    string addr_alloc_req = "addr_alloc_req";
};

namespace obj_name {
    string adata = "a_data";
    string dft = "/dif/mgmt/fa/" + obj_class::dft;
    string neighbors = "/daf/mgmt/" + obj_class::neighbors;
    string enrollment = "/daf/mgmt/" + obj_class::enrollment;
    string status = "/daf/mgmt/" + obj_class::status;
    string address = "/daf/mgmt/naming/" + obj_class::address;
    string lfdb = "/dif/mgmt/pduft/linkstate/" + obj_class::lfdb;
    string whatevercast = "/daf/mgmt/naming/whatevercast";
    string flows = "/dif/ra/fa/" + obj_class::flows;
    string keepalive = "/daf/mgmt/" + obj_class::keepalive;
    string lowerflow = "/daf/mgmt/" + obj_class::lowerflow;
    string addr_alloc_table = "/dif/ra/aa/" + obj_class::addr_alloc_table;
};

#define MGMTBUF_SIZE_MAX 8092

static int
mgmt_write(struct uipcp *uipcp, const struct rl_mgmt_hdr *mhdr,
           void *buf, size_t buflen)
{
    uipcp_rib *rib = UIPCP_RIB(uipcp);
    char *mgmtbuf;
    int n;
    int ret = 0;

    if (buflen > MGMTBUF_SIZE_MAX) {
        errno = EFBIG;
        return -1;
    }

    mgmtbuf = (char *)rl_alloc(sizeof(*mhdr) + buflen, RL_MT_MISC);
    if (!mgmtbuf) {
        errno = ENOMEM;
        return -1;
    }

    memcpy(mgmtbuf, mhdr, sizeof(*mhdr));
    memcpy(mgmtbuf + sizeof(*mhdr), buf, buflen);
    buflen += sizeof(*mhdr);

    n = write(rib->mgmtfd, mgmtbuf, buflen);
    if (n < 0) {
        ret = n;
    } else {
        assert(n == (int)buflen);
    }

    rl_free(mgmtbuf, RL_MT_MISC);

    return ret;
}

int
mgmt_write_to_local_port(struct uipcp *uipcp, rl_port_t local_port,
                         void *buf, size_t buflen)
{
    struct rl_mgmt_hdr mhdr;

    memset(&mhdr, 0, sizeof(mhdr));
    mhdr.type = RLITE_MGMT_HDR_T_OUT_LOCAL_PORT;
    mhdr.local_port = local_port;

    return mgmt_write(uipcp, &mhdr, buf, buflen);
}

int
mgmt_write_to_dst_addr(struct uipcp *uipcp, rl_addr_t dst_addr,
                       void *buf, size_t buflen)
{
    struct rl_mgmt_hdr mhdr;

    memset(&mhdr, 0, sizeof(mhdr));
    mhdr.type = RLITE_MGMT_HDR_T_OUT_DST_ADDR;
    mhdr.remote_addr = dst_addr;

    return mgmt_write(uipcp, &mhdr, buf, buflen);
}

static int
rib_recv_msg(struct uipcp_rib *rib, struct rl_mgmt_hdr *mhdr,
             char *serbuf, int serlen)
{
    CDAPMessage *m = NULL;
    Neighbor *neigh;
    NeighFlow *nf;
    int ret;

    try {
        m = msg_deser_stateless(serbuf, serlen);
        if (m == NULL) {
            return -1;
        }
        rl_mt_adjust(1, RL_MT_CDAP);

        if (m->obj_class == obj_class::adata &&
                    m->obj_name == obj_name::adata) {
            /* A-DATA message, does not belong to any CDAP
             * session. */
            const char *objbuf;
            size_t objlen;

            m->get_obj_value(objbuf, objlen);
            if (!objbuf) {
                UPE(rib->uipcp, "CDAP message does not contain a nested message\n");

                cdap_msg_delete(m);
                return 0;
            }

            AData adata(objbuf, objlen);

            if (!adata.cdap) {
                UPE(rib->uipcp, "A_DATA does not contain a valid "
                                "encapsulated CDAP message\n");

                cdap_msg_delete(m);
                return 0;
            }

            ScopeLock(rib->lock);

            rib->cdap_dispatch(adata.cdap, NULL);<commit_msg>uipcps: rib_msg_recv: remove memory leak<commit_after>/*
 * Core implementation of normal uipcps.
 *
 * Copyright (C) 2015-2016 Nextworks
 * Author: <NAME> <<EMAIL>>
 *
 * This file is part of rlite.
 *
 * 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.1 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 library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <vector>
#include <list>
#include <map>
#include <string>
#include <iostream>
#include <fstream>
#include <cstring>
#include <sstream>
#include <unistd.h>
#include <stdint.h>
#include <cstdlib>
#include <cassert>
#include <cerrno>
#include <pthread.h>
#include <poll.h>

#include <rlite/conf.h>

#include "uipcp-normal.hpp"

using namespace std;


namespace obj_class {
    string adata = "a_data";
    string dft = "dft";
    string neighbors = "neighbors";
    string enrollment = "enrollment";
    string status = "operational_status";
    string address = "address";
    string lfdb = "fsodb"; /* Lower Flow DB */
    string flows = "flows"; /* Supported flows */
    string flow = "flow";
    string keepalive = "keepalive";
    string lowerflow = "lowerflow";
    string addr_alloc_table = "addr_alloc_table";
    string addr_alloc_req = "addr_alloc_req";
};

namespace obj_name {
    string adata = "a_data";
    string dft = "/dif/mgmt/fa/" + obj_class::dft;
    string neighbors = "/daf/mgmt/" + obj_class::neighbors;
    string enrollment = "/daf/mgmt/" + obj_class::enrollment;
    string status = "/daf/mgmt/" + obj_class::status;
    string address = "/daf/mgmt/naming/" + obj_class::address;
    string lfdb = "/dif/mgmt/pduft/linkstate/" + obj_class::lfdb;
    string whatevercast = "/daf/mgmt/naming/whatevercast";
    string flows = "/dif/ra/fa/" + obj_class::flows;
    string keepalive = "/daf/mgmt/" + obj_class::keepalive;
    string lowerflow = "/daf/mgmt/" + obj_class::lowerflow;
    string addr_alloc_table = "/dif/ra/aa/" + obj_class::addr_alloc_table;
};

#define MGMTBUF_SIZE_MAX 8092

static int
mgmt_write(struct uipcp *uipcp, const struct rl_mgmt_hdr *mhdr,
           void *buf, size_t buflen)
{
    uipcp_rib *rib = UIPCP_RIB(uipcp);
    char *mgmtbuf;
    int n;
    int ret = 0;

    if (buflen > MGMTBUF_SIZE_MAX) {
        errno = EFBIG;
        return -1;
    }

    mgmtbuf = (char *)rl_alloc(sizeof(*mhdr) + buflen, RL_MT_MISC);
    if (!mgmtbuf) {
        errno = ENOMEM;
        return -1;
    }

    memcpy(mgmtbuf, mhdr, sizeof(*mhdr));
    memcpy(mgmtbuf + sizeof(*mhdr), buf, buflen);
    buflen += sizeof(*mhdr);

    n = write(rib->mgmtfd, mgmtbuf, buflen);
    if (n < 0) {
        ret = n;
    } else {
        assert(n == (int)buflen);
    }

    rl_free(mgmtbuf, RL_MT_MISC);

    return ret;
}

int
mgmt_write_to_local_port(struct uipcp *uipcp, rl_port_t local_port,
                         void *buf, size_t buflen)
{
    struct rl_mgmt_hdr mhdr;

    memset(&mhdr, 0, sizeof(mhdr));
    mhdr.type = RLITE_MGMT_HDR_T_OUT_LOCAL_PORT;
    mhdr.local_port = local_port;

    return mgmt_write(uipcp, &mhdr, buf, buflen);
}

int
mgmt_write_to_dst_addr(struct uipcp *uipcp, rl_addr_t dst_addr,
                       void *buf, size_t buflen)
{
    struct rl_mgmt_hdr mhdr;

    memset(&mhdr, 0, sizeof(mhdr));
    mhdr.type = RLITE_MGMT_HDR_T_OUT_DST_ADDR;
    mhdr.remote_addr = dst_addr;

    return mgmt_write(uipcp, &mhdr, buf, buflen);
}

static int
rib_recv_msg(struct uipcp_rib *rib, struct rl_mgmt_hdr *mhdr,
             char *serbuf, int serlen)
{
    CDAPMessage *m = NULL;
    Neighbor *neigh;
    NeighFlow *nf;
    int ret;

    try {
        m = msg_deser_stateless(serbuf, serlen);
        if (m == NULL) {
            return -1;
        }
        rl_mt_adjust(1, RL_MT_CDAP);

        if (m->obj_class == obj_class::adata &&
                    m->obj_name == obj_name::adata) {
            /* A-DATA message, does not belong to any CDAP
             * session. */
            const char *objbuf;
            size_t objlen;

            m->get_obj_value(objbuf, objlen);
            if (!objbuf) {
                UPE(rib->uipcp, "CDAP message does not contain a nested message\n");

                cdap_msg_delete(m);
                return 0;
            }

            AData adata(objbuf, objlen);

            cdap_msg_delete(m); /* here it is safe to delete m */
            if (!adata.cdap) {
                UPE(rib->uipcp, "A_DATA does not contain a valid "
                                "encapsulated CDAP message\n");

                return 0;
            }

            ScopeLock(rib->lock);

            rib->cdap_dispatch(adata.cdap, NULL);
{'fraction_non_alphanumeric': 0.11562712193229217, 'fraction_numerical': 0.006790183334950043, 'mean_word_length': 2.602375960866527, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4796597', 'n_tokens_mistral': 3696, 'n_tokens_neox': 3542, 'n_words': 956}