Preparations for 6.2.0

Openssl 3.0 and autoconf 2.71
This commit is contained in:
Olof hagsand 2023-04-29 15:57:22 +02:00
parent 4643540391
commit 5d1c6b5759
8 changed files with 2764 additions and 2151 deletions

View file

@ -380,143 +380,6 @@ netconf_input_packet(clicon_handle h,
return retval;
}
#ifndef NETCONF_INPUT_UNIFIED_EXTERN
/*! Process incoming frame, ie a char message framed by ]]>]]>
* Parse string to xml, check only one netconf message within a frame
* @param[in] h Clixon handle
* @param[in] cb Packet buffer
* @param[out] eof Set to 1 if pending close socket
* @retval 0 OK
* @retval -1 Fatal error
* @note there are errors detected here prior to whether you know what kind if message it is, and
* these errors are returned as "rpc-error".
* This is problematic since RFC6241 only says to return rpc-error on errors to <rpc>.
* Not at this early stage, the incoming message can be something else such as <hello> or
* something else.
* In section 8.1 regarding handling of <hello> it says just to "terminate" the session which I
* interpret as not sending anything back, just closing the session.
* Anyway, clixon therefore does the following on error:
* - Before we know what it is: send rpc-error
* - Hello messages: terminate
* - RPC messages: send rpc-error
*/
static int
netconf_input_frame1(clicon_handle h,
cbuf *cb,
int *eof)
{
int retval = -1;
char *str = NULL;
cxobj *xtop = NULL; /* Request (in) */
cxobj *xreq = NULL;
cxobj *xret = NULL; /* Return (out) */
cbuf *cbret = NULL;
yang_stmt *yspec;
int ret;
netconf_framing_type framing;
clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
clicon_debug(CLIXON_DBG_MSG, "Recv ext: %s", cbuf_get(cb));
framing = clicon_data_int_get(h, NETCONF_FRAMING_TYPE);
yspec = clicon_dbspec_yang(h);
if ((str = strdup(cbuf_get(cb))) == NULL){
clicon_err(OE_UNIX, errno, "strdup");
goto done;
}
/* Special case: */
if (strlen(str) == 0){
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (netconf_operation_failed(cbret, "rpc", "Empty XML")< 0)
goto done;
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
/* Parse incoming XML message */
if ((ret = clixon_xml_parse_string(str, YB_RPC, yspec, &xtop, &xret)) < 0){
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (netconf_operation_failed(cbret, "rpc", clicon_err_reason)< 0)
goto done;
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
if (ret == 0){
/* Note: xtop can be "hello" in which case one (maybe) should drop the session and log
* However, its not until netconf_input_packet that rpc vs hello vs other identification is
* actually made.
* Actually, there are no error replies to hello messages according to any RFC, so
* rpc error reply here is non-standard, but may be useful.
*/
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
if (clixon_xml2cbuf(cbret, xret, 0, 0, NULL, -1, 0) < 0)
goto done;
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
/* Check for empty frame (no mesaages), return empty message, not clear from RFC what to do */
if (xml_child_nr_type(xtop, CX_ELMNT) == 0){
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
/* Check for multi-messages in frame */
if (xml_child_nr_type(xtop, CX_ELMNT) != 1){
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (netconf_malformed_message(cbret, "More than one message in netconf rpc frame")< 0)
goto done;
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
if ((xreq = xml_child_i_type(xtop, 0, CX_ELMNT)) == NULL){ /* Shouldnt happen */
clicon_err(OE_XML, EFAULT, "No xml req (shouldnt happen)");
goto done;
}
if (netconf_input_packet(h, xreq, yspec, eof) < 0)
goto done;
ok:
retval = 0;
done:
if (str)
free(str);
if (xtop)
xml_free(xtop);
if (xret)
xml_free(xret);
if (cbret)
cbuf_free(cbret);
return retval;
}
#endif /* NETCONF_INPUT_UNIFIED_EXTERN */
/*! Get netconf message: detect end-of-msg
* @param[in] s Socket where input arrived. read from this.
* @param[in] arg Clixon handle.
@ -528,7 +391,6 @@ netconf_input_frame1(clicon_handle h,
* <a>foo ..pause.. </a>]]>]]>
* then only "</a>" would be delivered to netconf_input_frame().
*/
#ifdef NETCONF_INPUT_UNIFIED_EXTERN
static int
netconf_input_cb(int s,
void *arg)
@ -659,137 +521,6 @@ netconf_input_cb(int s,
return retval;
}
#else /* NETCONF_INPUT_UNIFIED_EXTERN */
static int
netconf_input_cb(int s,
void *arg)
{
int retval = -1;
unsigned char buf[BUFSIZ]; /* from stdio.h, typically 8K */
clicon_handle h = arg;
cbuf *cb=NULL;
void *ptr;
size_t cdatlen = 0;
clicon_hash_t *cdat = clicon_data(h); /* Save cbuf between calls if not done */
int poll;
int i;
int len;
int frame_state;
size_t frame_size;
int ret;
int eof = 0; /* Set to 1 if pending close socket */
if (clicon_option_exists(h, NETCONF_FRAME_STATE) == 0)
frame_state = 0;
else
if ((frame_state = clicon_option_int(h, NETCONF_FRAME_STATE)) < 0)
goto done;
if (clicon_option_exists(h, NETCONF_FRAME_SIZE) == 0)
frame_size = 0;
else{
if ((ret = clicon_option_int(h, NETCONF_FRAME_SIZE)) < 0)
goto done;
frame_size = (size_t)ret;
}
if ((ptr = clicon_hash_value(cdat, NETCONF_FRAME_MSG, &cdatlen)) != NULL){
if (cdatlen != sizeof(cb)){
clicon_err(OE_XML, errno, "size mismatch %lu %lu",
(unsigned long)cdatlen, (unsigned long)sizeof(cb));
goto done;
}
cb = *(cbuf**)ptr;
clicon_hash_del(cdat, NETCONF_FRAME_MSG);
}
else{
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
}
memset(buf, 0, sizeof(buf));
while (1){
if ((len = read(s, buf, sizeof(buf))) < 0){
if (errno == ECONNRESET)
len = 0; /* emulate EOF */
else{
clicon_log(LOG_ERR, "%s: read: %s", __FUNCTION__, strerror(errno));
goto done;
}
} /* read */
if (len == 0){ /* EOF */
clicon_debug(1, "%s len==0, closing", __FUNCTION__);
clixon_event_unreg_fd(s, netconf_input_cb);
close(s);
clixon_exit_set(1);
goto ok;
}
for (i=0; i<len; i++){
if (buf[i] == 0)
continue; /* Skip NULL chars (eg from terminals) */
if (clicon_data_int_get(h, NETCONF_FRAMING_TYPE) == NETCONF_SSH_CHUNKED){
/* Track chunked framing defined in RFC6242 */
if ((ret = netconf_input_chunked_framing(buf[i], &frame_state, &frame_size)) < 0)
goto done;
switch (ret){
case 1: /* chunk-data */
cprintf(cb, "%c", buf[i]);
break;
case 2: /* end-of-data */
/* Somewhat complex error-handling:
* Ignore packet errors, UNLESS an explicit termination request (eof)
*/
if (netconf_input_frame1(h, cb, &eof) < 0 &&
!ignore_packet_errors)
goto done;
if (eof)
goto done;
cbuf_reset(cb);
break;
default:
break;
}
}
else{
cprintf(cb, "%c", buf[i]);
if (detect_endtag("]]>]]>", buf[i], &frame_state)){
frame_state = 0;
/* OK, we have an xml string from a client */
/* Remove trailer */
*(((char*)cbuf_get(cb)) + cbuf_len(cb) - strlen("]]>]]>")) = '\0';
if (netconf_input_frame1(h, cb, &eof) < 0 &&
!ignore_packet_errors) // default is to ignore errors
goto done;
if (eof)
goto done;
cbuf_reset(cb);
}
}
}
/* poll==1 if more, poll==0 if none */
if ((poll = clixon_event_poll(s)) < 0)
goto done;
if (poll == 0){
/* No data to read, save data and continue on next round */
if (cbuf_len(cb) != 0){
if (clicon_hash_add(cdat, NETCONF_FRAME_MSG, &cb, sizeof(cb)) == NULL)
goto done;
cb = NULL;
}
break;
}
} /* while */
ok:
clicon_option_int_set(h, NETCONF_FRAME_STATE, frame_state);
clicon_option_int_set(h, NETCONF_FRAME_SIZE, frame_size);
retval = 0;
done:
if (cb)
cbuf_free(cb);
return retval;
}
#endif /* NETCONF_INPUT_UNIFIED_EXTERN */
/*! Send netconf hello message
* @param[in] h Clixon handle
* @param[in] s File descriptor to write on (eg 1 - stdout)