Beispiel #1
0
/********************************************************************
* FUNCTION rpc_new_msg
*
* Malloc and initialize a new rpc_msg_t struct
*
* INPUTS:
*   none
* RETURNS:
*   pointer to struct or NULL or memory error
*********************************************************************/
rpc_msg_t *
    rpc_new_msg (void)
{
    rpc_msg_t *msg;

    msg = m__getObj(rpc_msg_t);
    if (!msg) {
        return NULL;
    }

    memset(msg, 0x0, sizeof(rpc_msg_t));
    xml_msg_init_hdr(&msg->mhdr);
    dlq_createSQue(&msg->rpc_dataQ);

    msg->rpc_input = val_new_value();
    if (!msg->rpc_input) {
        rpc_free_msg(msg);
        return NULL;
    }

    msg->rpc_top_editop = OP_EDITOP_MERGE;

    return msg;

} /* rpc_new_msg */
Beispiel #2
0
/********************************************************************
* FUNCTION mgr_rpc_new_request
*
* Malloc and initialize a new mgr_rpc_req_t struct
*
* INPUTS:
*   scb == session control block
*
* RETURNS:
*   pointer to struct or NULL or memory error
*********************************************************************/
mgr_rpc_req_t *
    mgr_rpc_new_request (ses_cb_t *scb)
{
    mgr_scb_t       *mscb;
    mgr_rpc_req_t   *req;
    char             numbuff[NCX_MAX_NUMLEN];

    req = m__getObj(mgr_rpc_req_t);
    if (!req) {
        return NULL;
    }
    memset(req, 0x0, sizeof(mgr_rpc_req_t));

    mscb = mgr_ses_get_mscb(scb);
    sprintf(numbuff, "%u", mscb->next_id);
    if (mscb->next_id >= MGR_MAX_REQUEST_ID) {
        mscb->next_id = 0;
    } else {
        mscb->next_id++;
    }

    req->msg_id = xml_strdup((const xmlChar *)numbuff);
    if (req->msg_id) {
        xml_msg_init_hdr(&req->mhdr);
        xml_init_attrs(&req->attrs);
    } else {
        m__free(req);
        req = NULL;
    }
    return req;

} /* mgr_rpc_new_request */
Beispiel #3
0
/********************************************************************
* FUNCTION mgr_hello_send
*
* Send the manager <hello> message to the server on the 
* specified session
*
* INPUTS:
*   scb == session control block
*
* RETURNS:
*   status
*********************************************************************/
status_t
    mgr_hello_send (ses_cb_t *scb)
{
    val_value_t  *mycaps;
    xml_msg_hdr_t msg;
    status_t      res;
    xml_attrs_t   attrs;
    boolean       anyout;
    xmlns_id_t    nc_id;

#ifdef DEBUG
    if (!scb) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif

#ifdef MGR_HELLO_DEBUG
    if (LOGDEBUG2) {
        log_debug2("\nmgr sending hello on session %d", scb->sid);
    }
#endif

    res = NO_ERR;
    anyout = FALSE;
    xml_msg_init_hdr(&msg);
    xml_init_attrs(&attrs);
    nc_id = xmlns_nc_id();

    /* get my client caps, custom made for this session */
    mycaps = mgr_cap_get_ses_capsval(scb);
    if (!mycaps) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    }

    /* setup the prefix map with the NETCONF namespace */
    if (res == NO_ERR) {
        res = xml_msg_build_prefix_map(&msg, &attrs, TRUE, FALSE);
    }

    /* send the <?xml?> directive */
    if (res == NO_ERR) {
        res = ses_start_msg(scb);
    }

    /* start the hello element */
    if (res == NO_ERR) {
        anyout = TRUE;
        xml_wr_begin_elem_ex(scb, 
                             &msg, 
                             0, 
                             nc_id, 
                             NCX_EL_HELLO, 
                             &attrs, 
                             ATTRQ, 
                             0, 
                             START);
    }
    
    /* send the capabilities list */
    if (res == NO_ERR) {
        xml_wr_full_val(scb, &msg, mycaps, NCX_DEF_INDENT);
    }

    /* finish the hello element */
    if (res == NO_ERR) {
        xml_wr_end_elem(scb, &msg, nc_id, NCX_EL_HELLO, 0);
    }

    /* finish the message */
    if (anyout) {
        ses_finish_msg(scb);
    }

    xml_clean_attrs(&attrs);
    xml_msg_clean_hdr(&msg);
    if (mycaps != NULL) {
        val_free_value(mycaps);
    }
    return res;

} /* mgr_hello_send */
Beispiel #4
0
/********************************************************************
* FUNCTION mgr_hello_dispatch
*
* Handle an incoming <hello> message from the client
*
* INPUTS:
*   scb == session control block
*   top == top element descriptor
*********************************************************************/
void 
    mgr_hello_dispatch (ses_cb_t *scb,
                        xml_node_t *top)
{
    val_value_t           *val;
    ncx_module_t          *mod;
    obj_template_t        *obj;
    mgr_scb_t             *mscb;
    xml_msg_hdr_t          msg;
    status_t               res;

#ifdef DEBUG
    if (!scb || !top) {
        SET_ERROR(ERR_INTERNAL_PTR);
        return;
    }
#endif

#ifdef MGR_HELLO_DEBUG
    if (LOGDEBUG) {
        log_debug("\nmgr_hello got node");
    }
    if (LOGDEBUG2) {
        xml_dump_node(top);
    }
#endif

    mscb = mgr_ses_get_mscb(scb);

    /* only process this message in hello wait state */
    if (scb->state != SES_ST_HELLO_WAIT) {
        /* TBD: stats update */
        if (LOGINFO) {
            log_info("\nmgr_hello dropped, wrong state for session %d",
                     scb->sid);
        }
        return;
    }

    /* init local vars */
    res = NO_ERR;
    val = NULL;
    obj = NULL;
    xml_msg_init_hdr(&msg);

    /* get a value struct to hold the server hello msg */
    val = val_new_value();
    if (!val) {
        res = ERR_INTERNAL_MEM;
    }

    /* get the type definition from the registry */
    if (res == NO_ERR) {
        mod = ncx_find_module(NC_MODULE, NULL);
        if (mod) {
            obj = ncx_find_object(mod, MGR_SERVER_HELLO_OBJ);
        }
        if (!obj) {
            /* netconf module should have loaded this definition */
            res = SET_ERROR(ERR_INTERNAL_PTR);
        }
    }

    /* parse an server hello message */
    if (res == NO_ERR) {
        res = mgr_val_parse(scb, obj, top, val);
    }
    
    /* examine the server capability list
     * and it matches the server protocol version
     */
    if (res == NO_ERR) {
        res = process_server_hello(scb, val);
    }

    /* report first error and close session */
    if (res != NO_ERR) {
        if (LOGINFO) {
            log_info("\nmgr_connect error (%s)\n  dropping session %u (a:%u)",
                     get_error_string(res), 
                     scb->sid, 
                     mscb->agtsid,
                     res);
        }
    } else {
        scb->state = SES_ST_IDLE;
        if (LOGDEBUG) {
            log_debug("\nmgr_hello manager hello ok");
        }
    }
    if (val) {
        val_free_value(val);
    }

} /* mgr_hello_dispatch */
Beispiel #5
0
/********************************************************************
* FUNCTION agt_hello_send
*
* Send the server <hello> message to the manager on the 
* specified session
*
* INPUTS:
*   scb == session control block
*
* RETURNS:
*   status
*********************************************************************/
status_t
    agt_hello_send (ses_cb_t *scb)
{
    assert( scb && "scb is NULL!" );
    
    status_t res = NO_ERR;
    boolean anyout = FALSE;
    xmlns_id_t nc_id = xmlns_nc_id();

    xml_msg_hdr_t msg;
    xml_msg_init_hdr(&msg);

    xml_attrs_t attrs;
    xml_init_attrs(&attrs);

    /* start the hello timeout */
    (void)time(&scb->hello_time);

    /* get the server caps */
    val_value_t *mycaps = agt_cap_get_capsval();
    if (!mycaps) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    }

    /* setup the prefix map with the NETCONF and NCX namepsaces */
    if (res == NO_ERR) {
        res = xml_msg_build_prefix_map(&msg, &attrs, TRUE, FALSE);
    }

    /* send the <?xml?> directive */
    if (res == NO_ERR) {
        res = ses_start_msg(scb);
    }

    boolean mode_started = FALSE;
    if (res == NO_ERR) {
        ses_start_msg_mode(scb);
        mode_started = TRUE;
    }

    int32 msg_indent = ses_message_indent_count(scb);

    /* start the hello element */
    if (res == NO_ERR) {
        anyout = TRUE;
        xml_wr_begin_elem_ex(scb, &msg, 0, nc_id, NCX_EL_HELLO, 
                             &attrs, TRUE, max(msg_indent, 0), FALSE);
    }
    
    /* send the capabilities list */
    if (res == NO_ERR) {
        xml_wr_full_val(scb, &msg, mycaps, msg_indent);
    }

    /* send the session ID */
    if (res == NO_ERR) {
        xml_wr_begin_elem(scb, &msg, nc_id, nc_id, NCX_EL_SESSION_ID, 
                          msg_indent);

    }
    if (res == NO_ERR) {
        xmlChar numbuff[NCX_MAX_NUMLEN];
        snprintf((char *)numbuff, sizeof(numbuff), "%d", scb->sid);
        ses_putstr(scb, numbuff);
    }
    if (res == NO_ERR) {
        xml_wr_end_elem(scb, &msg, nc_id, NCX_EL_SESSION_ID, -1);
    }

    /* finish the hello element */
    if (res == NO_ERR) {
        xml_wr_end_elem(scb, &msg, nc_id, NCX_EL_HELLO, max(msg_indent, 0));
    }

    /* finish the message */
    if (anyout) {
        ses_finish_msg(scb);
    }

    if (mode_started) {
        ses_stop_msg_mode(scb);
    }

    xml_clean_attrs(&attrs);
    xml_msg_clean_hdr(&msg);
    return res;

} /* agt_hello_send */
Beispiel #6
0
/********************************************************************
* FUNCTION agt_hello_dispatch
*
* Handle an incoming <hello> message from the client
*
* INPUTS:
*   scb == session control block
*   top == top element descriptor
*********************************************************************/
void 
    agt_hello_dispatch (ses_cb_t *scb,
                        xml_node_t *top)
{
    assert( scb && "scb is NULL!" );
    assert( top && "top is NULL!" );

    if (LOGDEBUG2) {
        log_debug2("\nagt_hello: got node");
        if (LOGDEBUG3) {
            xml_dump_node(top);
        }
    }

    /* only process this message in hello wait state */
    if (scb->state != SES_ST_HELLO_WAIT) {
        log_info("\nagt_hello dropped, wrong state "
                 "(%d) for session %d", scb->state, scb->sid);
        mytotals->inBadHellos++;
        mytotals->droppedSessions++;
        agt_ses_request_close(scb, scb->sid, SES_TR_BAD_HELLO);
        return;
    }

    /* init local vars */
    status_t res = NO_ERR;
    obj_template_t *obj = NULL;
    xml_msg_hdr_t msg;
    xml_msg_init_hdr(&msg);

    /* get a value struct to hold the client hello msg */
    val_value_t *val = val_new_value();
    if (!val) {
        res = ERR_INTERNAL_MEM;
    }

    /* get the type definition from the registry */
    if (res == NO_ERR) {
        ncx_module_t *mod = ncx_find_module(NC_MODULE, NULL);
        if (mod) {
            obj = ncx_find_object(mod, CLIENT_HELLO_CON);
        }
        if (!obj) {
            /* netconf module should have loaded this definition */
            res = SET_ERROR(ERR_INTERNAL_PTR);
        }
    }

    /* parse a manager hello message */
    if (res == NO_ERR) {
        res = agt_val_parse_nc(scb, &msg, obj, top, NCX_DC_STATE, val);
    }
    
    /* check that the NETCONF base capability is included
     * and it matches the server protocol version
     */
    if (res == NO_ERR) {
        res = check_manager_hello(scb, val);
    }

    /* report first error and close session */
    if (res != NO_ERR) {
        if (LOGINFO) {
            log_info("\nagt_connect error (%s), dropping session %d",
                     get_error_string(res), scb->sid);
        }
        mytotals->inBadHellos++;
        mytotals->droppedSessions++;
        agt_ses_request_close(scb, scb->sid, SES_TR_BAD_HELLO);

    } else {
        scb->state = SES_ST_IDLE;
        scb->active = TRUE;
        /* start the timer for the first rpc request */
        (void)time(&scb->last_rpc_time);

        if (LOGDEBUG) {
            log_debug("\nSession %d for %s@%s now active", 
                      scb->sid, scb->username, scb->peeraddr);
            if (ses_get_protocol(scb) == NCX_PROTO_NETCONF11) {
                log_debug_append(" (base:1.1)");
            } else {
                log_debug_append(" (base:1.0)");
            }
        }
    }

    if (val) {
        val_free_value(val);
    }

} /* agt_hello_dispatch */
Beispiel #7
0
/********************************************************************
* FUNCTION mgr_rpc_send_request
*
* Send an <rpc> request to the agent on the specified session
* non-blocking send, reply function will be called when
* one is received or a timeout occurs
*
* INPUTS:
*   scb == session control block
*   req == request to send
*   rpyfn == reply callback function
*
* RETURNS:
*   status
*********************************************************************/
status_t
    mgr_rpc_send_request (ses_cb_t *scb,
                          mgr_rpc_req_t *req,
                          mgr_rpc_cbfn_t rpyfn)
{
    xml_msg_hdr_t msg;
    xml_attr_t   *attr;
    status_t      res;
    boolean       anyout;
    xmlns_id_t    nc_id;

#ifdef DEBUG
    if (!scb || !req || !rpyfn) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif

#ifdef MGR_HELLO_DEBUG
    log_debug2("\nmgr sending RPC request %s on session %d", 
               req->msg_id, scb->sid);
#endif

    anyout = FALSE;
    xml_msg_init_hdr(&msg);
    nc_id = xmlns_nc_id();

    /* make sure the message-id attribute is not already present */
    attr = xml_find_attr_q(&req->attrs, 0, NCX_EL_MESSAGE_ID);
    if (attr) {
        dlq_remove(attr);
        xml_free_attr(attr);
    }

    /* setup the prefix map with the NETCONF (and maybe NCX) namespace */
    res = xml_msg_build_prefix_map(&msg, 
                                   &req->attrs, 
                                   FALSE, 
                                   (req->data->nsid == xmlns_ncx_id()));

    /* add the message-id attribute */
    if (res == NO_ERR) {
        res = xml_add_attr(&req->attrs, 
                           0, 
                           NCX_EL_MESSAGE_ID,
                           req->msg_id);
    }

    /* set perf timestamp in case response timing active */
    gettimeofday(&req->perfstarttime, NULL);     

    /* send the <?xml?> directive */
    if (res == NO_ERR) {
        res = ses_start_msg(scb);
    }

    /* start the <rpc> element */
    if (res == NO_ERR) {
        anyout = TRUE;
        xml_wr_begin_elem_ex(scb, 
                             &msg, 
                             0, 
                             nc_id, 
                             NCX_EL_RPC, 
                             &req->attrs, 
                             ATTRQ, 
                             0, 
                             START);
    }
    
    /* send the method and parameters */
    if (res == NO_ERR) {
        xml_wr_full_val(scb, &msg, req->data, NCX_DEF_INDENT);
    }

    /* finish the <rpc> element */
    if (res == NO_ERR) {
        xml_wr_end_elem(scb, &msg, nc_id, NCX_EL_RPC, 0);
    }

    /* finish the message */
    if (anyout) {
        ses_finish_msg(scb);
    }

    if (res == NO_ERR) {
        req->replycb = rpyfn;
        add_request(scb, req);
    }

    xml_msg_clean_hdr(&msg);
    return res;

}  /* mgr_rpc_send_request */