- Restconf native: Fixed ssl/non-ssl read/write behaviour for data that is different in freebsd than in linux
- test: removed sed -i in tests since it is not portable between linux and bsd
This commit is contained in:
parent
940f4d4fb9
commit
b31107f646
4 changed files with 64 additions and 15 deletions
|
|
@ -679,6 +679,8 @@ restconf_connection(int s,
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
char buf[BUFSIZ]; /* from stdio.h, typically 8K XXX: reduce for test */
|
char buf[BUFSIZ]; /* from stdio.h, typically 8K XXX: reduce for test */
|
||||||
int readmore = 1;
|
int readmore = 1;
|
||||||
|
int sslerr;
|
||||||
|
|
||||||
#ifdef HAVE_LIBEVHTP
|
#ifdef HAVE_LIBEVHTP
|
||||||
clicon_handle h;
|
clicon_handle h;
|
||||||
evhtp_connection_t *evconn = NULL;
|
evhtp_connection_t *evconn = NULL;
|
||||||
|
|
@ -700,21 +702,47 @@ restconf_connection(int s,
|
||||||
curl -Ssik --key /var/tmp/./test_restconf_ssl_certs.sh/certs/limited.key --cert /var/tmp/./test_restconf_ssl_certs.sh/certs/limited.crt -X GET https://localhost/restconf/data/example:x
|
curl -Ssik --key /var/tmp/./test_restconf_ssl_certs.sh/certs/limited.key --cert /var/tmp/./test_restconf_ssl_certs.sh/certs/limited.crt -X GET https://localhost/restconf/data/example:x
|
||||||
*/
|
*/
|
||||||
if ((n = SSL_read(rc->rc_ssl, buf, sizeof(buf))) < 0){
|
if ((n = SSL_read(rc->rc_ssl, buf, sizeof(buf))) < 0){
|
||||||
|
sslerr = SSL_get_error(rc->rc_ssl, n);
|
||||||
|
clicon_debug(1, "%s SSL_read() n:%ld errno:%d sslerr:%d", __FUNCTION__, n, errno, sslerr);
|
||||||
|
switch (sslerr){
|
||||||
|
case SSL_ERROR_WANT_READ: /* 2 */
|
||||||
|
/* SSL_ERROR_WANT_READ is returned when the last operation was a read operation
|
||||||
|
* from a nonblocking BIO.
|
||||||
|
* That is, it can happen if restconf_socket_init() below is called
|
||||||
|
* with SOCK_NONBLOCK
|
||||||
|
*/
|
||||||
|
clicon_debug(1, "%s SSL_read SSL_ERROR_WANT_READ", __FUNCTION__);
|
||||||
|
usleep(1000);
|
||||||
|
readmore = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
clicon_err(OE_XML, errno, "SSL_read");
|
clicon_err(OE_XML, errno, "SSL_read");
|
||||||
goto done;
|
goto done;
|
||||||
|
} /* switch */
|
||||||
|
continue; /* readmore */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if ((n = read(rc->rc_s, buf, sizeof(buf))) < 0){ /* XXX atomicio ? */
|
if ((n = read(rc->rc_s, buf, sizeof(buf))) < 0){ /* XXX atomicio ? */
|
||||||
if (errno == ECONNRESET) {/* Connection reset by peer */
|
switch(errno){
|
||||||
|
case ECONNRESET:/* Connection reset by peer */
|
||||||
clicon_debug(1, "%s %d Connection reset by peer", __FUNCTION__, rc->rc_s);
|
clicon_debug(1, "%s %d Connection reset by peer", __FUNCTION__, rc->rc_s);
|
||||||
clixon_event_unreg_fd(rc->rc_s, restconf_connection);
|
clixon_event_unreg_fd(rc->rc_s, restconf_connection);
|
||||||
close(rc->rc_s);
|
close(rc->rc_s);
|
||||||
restconf_conn_free(rc);
|
restconf_conn_free(rc);
|
||||||
goto ok; /* Close socket and ssl */
|
goto ok; /* Close socket and ssl */
|
||||||
}
|
break;
|
||||||
|
case EAGAIN:
|
||||||
|
clicon_debug(1, "%s read EAGAIN", __FUNCTION__);
|
||||||
|
usleep(1000);
|
||||||
|
readmore = 1;
|
||||||
|
break;
|
||||||
|
default:;
|
||||||
clicon_err(OE_XML, errno, "read");
|
clicon_err(OE_XML, errno, "read");
|
||||||
goto done;
|
goto done;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clicon_debug(1, "%s read:%ld", __FUNCTION__, n);
|
clicon_debug(1, "%s read:%ld", __FUNCTION__, n);
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,7 @@ session_send_callback(nghttp2_session *session,
|
||||||
ssize_t totlen = 0;
|
ssize_t totlen = 0;
|
||||||
int s;
|
int s;
|
||||||
SSL *ssl;
|
SSL *ssl;
|
||||||
|
int sslerr;
|
||||||
|
|
||||||
clicon_debug(1, "%s buflen:%lu", __FUNCTION__, buflen);
|
clicon_debug(1, "%s buflen:%lu", __FUNCTION__, buflen);
|
||||||
s = rc->rc_s;
|
s = rc->rc_s;
|
||||||
|
|
@ -190,7 +191,14 @@ session_send_callback(nghttp2_session *session,
|
||||||
if (ssl){
|
if (ssl){
|
||||||
if ((len = SSL_write(ssl, buf+totlen, buflen-totlen)) <= 0){
|
if ((len = SSL_write(ssl, buf+totlen, buflen-totlen)) <= 0){
|
||||||
er = errno;
|
er = errno;
|
||||||
switch (SSL_get_error(ssl, len)){
|
sslerr = SSL_get_error(ssl, len);
|
||||||
|
clicon_debug(1, "%s errno:;%d sslerr:%d", __FUNCTION__, errno, sslerr);
|
||||||
|
switch (sslerr){
|
||||||
|
case SSL_ERROR_WANT_WRITE: /* 3 */
|
||||||
|
clicon_debug(1, "%s write SSL_ERROR_WANT_WRITE", __FUNCTION__);
|
||||||
|
usleep(1000);
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
case SSL_ERROR_SYSCALL: /* 5 */
|
case SSL_ERROR_SYSCALL: /* 5 */
|
||||||
if (er == ECONNRESET) {/* Connection reset by peer */
|
if (er == ECONNRESET) {/* Connection reset by peer */
|
||||||
if (ssl)
|
if (ssl)
|
||||||
|
|
@ -200,8 +208,12 @@ session_send_callback(nghttp2_session *session,
|
||||||
goto ok; /* Close socket and ssl */
|
goto ok; /* Close socket and ssl */
|
||||||
}
|
}
|
||||||
else if (er == EAGAIN){
|
else if (er == EAGAIN){
|
||||||
|
/* same as want_write above, but different behaviour on different
|
||||||
|
* platforms, linux here, freebsd want_write, or possibly differnt
|
||||||
|
* ssl lib versions?
|
||||||
|
*/
|
||||||
clicon_debug(1, "%s write EAGAIN", __FUNCTION__);
|
clicon_debug(1, "%s write EAGAIN", __FUNCTION__);
|
||||||
usleep(10000);
|
usleep(1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,9 @@ expectpart "$($clixon_cli -1 -f $cfg -l o debug restconf 1)" 0 "^$"
|
||||||
new "get and put config using restconf"
|
new "get and put config using restconf"
|
||||||
expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+xml" -X GET $RCPROTO://localhost/restconf/data?content=config --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data -d '{"example:table":{"parameter":{"name":"local0","value":"foo"}}}')" 0 "HTTP/$HVER 200" '<data>' "HTTP/$HVER 201"
|
expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+xml" -X GET $RCPROTO://localhost/restconf/data?content=config --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data -d '{"example:table":{"parameter":{"name":"local0","value":"foo"}}}')" 0 "HTTP/$HVER 200" '<data>' "HTTP/$HVER 201"
|
||||||
|
|
||||||
|
# In freebsd, backend dies in stop_restconf below unless sleep
|
||||||
|
sleep $DEMSLEEP
|
||||||
|
|
||||||
if [ $RC -ne 0 ]; then
|
if [ $RC -ne 0 ]; then
|
||||||
new "Kill restconf daemon"
|
new "Kill restconf daemon"
|
||||||
stop_restconf
|
stop_restconf
|
||||||
|
|
@ -115,7 +118,7 @@ if [ $BE -ne 0 ]; then
|
||||||
# Check if premature kill
|
# Check if premature kill
|
||||||
pid=$(pgrep -u root -f clixon_backend)
|
pid=$(pgrep -u root -f clixon_backend)
|
||||||
if [ -z "$pid" ]; then
|
if [ -z "$pid" ]; then
|
||||||
err "backend already dead"
|
err1 "backend pid !=0" 0
|
||||||
fi
|
fi
|
||||||
# kill backend
|
# kill backend
|
||||||
stop_backend -f $cfg
|
stop_backend -f $cfg
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ ftest=$dir/test.xml
|
||||||
fconfig=$dir/large.xml
|
fconfig=$dir/large.xml
|
||||||
fconfig2=$dir/large2.xml # leaf-list
|
fconfig2=$dir/large2.xml # leaf-list
|
||||||
foutput=$dir/output.xml
|
foutput=$dir/output.xml
|
||||||
|
foutput2=$dir/output2.xml
|
||||||
|
|
||||||
cat <<EOF > $fyang
|
cat <<EOF > $fyang
|
||||||
module scaling{
|
module scaling{
|
||||||
|
|
@ -132,15 +133,20 @@ expecteof "time -p $clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><co
|
||||||
|
|
||||||
new "Check running-db contents"
|
new "Check running-db contents"
|
||||||
curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data?content=config > $foutput
|
curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data?content=config > $foutput
|
||||||
|
r=$?
|
||||||
|
if [ $r -ne 0 ]; then
|
||||||
|
err1 "retval 0" $r
|
||||||
|
fi
|
||||||
|
|
||||||
# Remove Content-Length line (depends on size)
|
# Remove Content-Length line (depends on size)
|
||||||
sed -i '/Content-Length:/d' $foutput
|
# Note: do not use sed -i since it is not portable between gnu and bsd
|
||||||
sed -i '/content-length:/d' $foutput
|
sed '/Content-Length:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||||
|
sed '/content-length:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||||
# Remove (nginx) web-server specific lines
|
# Remove (nginx) web-server specific lines
|
||||||
sed -i '/Server:/d' $foutput
|
sed '/Server:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||||
sed -i '/Date:/d' $foutput
|
sed '/Date:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||||
sed -i '/Transfer-Encoding:/d' $foutput
|
sed '/Transfer-Encoding:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||||
sed -i '/Connection:/d' $foutput
|
sed '/Connection:/d' $foutput > $foutput2 && mv $foutput2 $foutput
|
||||||
|
|
||||||
# Create a file to compare with
|
# Create a file to compare with
|
||||||
if ${HAVE_LIBNGHTTP2}; then
|
if ${HAVE_LIBNGHTTP2}; then
|
||||||
|
|
@ -165,7 +171,7 @@ echo "</data>
" >> $ftest
|
||||||
|
|
||||||
ret=$(diff -i $ftest $foutput)
|
ret=$(diff -i $ftest $foutput)
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "$ret"
|
echo "diff -i $ftest $foutput"
|
||||||
err1 "Matching running-db with $fconfigonly"
|
err1 "Matching running-db with $fconfigonly"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue