Blame SOURCES/redhat-bugzilla-2030140.patch

689f35
diff -Naurp pcp-5.3.5.orig/qa/1458 pcp-5.3.5/qa/1458
689f35
--- pcp-5.3.5.orig/qa/1458	1970-01-01 10:00:00.000000000 +1000
689f35
+++ pcp-5.3.5/qa/1458	2021-12-09 11:25:01.973327231 +1100
689f35
@@ -0,0 +1,219 @@
689f35
+#!/bin/sh
689f35
+# PCP QA Test No. 1458
689f35
+# Exercise access pmproxy with secure.enabled = false
689f35
+#
689f35
+# The main purpose of this is to test that the component works correctly
689f35
+# when secure.enabled = false; we can expect the https URLs to fail.
689f35
+#
689f35
+# See https://github.com/performancecopilot/pcp/issues/1490
689f35
+
689f35
+# Copyright (c) 2019,2021 Red Hat
689f35
+# Modified by Netflix, Inc.
689f35
+#
689f35
+
689f35
+seq=`basename $0`
689f35
+echo "QA output created by $seq"
689f35
+
689f35
+# get standard environment, filters and checks
689f35
+. ./common.product
689f35
+. ./common.filter
689f35
+. ./common.check
689f35
+
689f35
+_check_series	# pmseries availability means libuv is in use
689f35
+_check_valgrind
689f35
+openssl help 2>/dev/null || _notrun "No openssl binary found"
689f35
+
689f35
+if [ -f /etc/lsb-release ]
689f35
+then
689f35
+    . /etc/lsb-release
689f35
+    if [ "$DISTRIB_ID" = Ubuntu ]
689f35
+    then
689f35
+	# This test fails for Ubuntu 19.10 with a myriad of errors involving
689f35
+	# the use of uninitialized values.  The code paths very but typically
689f35
+	# involve libuv -> libssl ->  libcrypto
689f35
+	#
689f35
+	case "$DISTRIB_RELEASE"
689f35
+	in
689f35
+	    19.10)
689f35
+		_notrun "problems with libuv, libssl, libcrypto and valgrind on Ubuntu $DISTRIB_RELEASE"
689f35
+		;;
689f35
+	esac
689f35
+    fi
689f35
+fi
689f35
+
689f35
+_cleanup()
689f35
+{
689f35
+    cd $here
689f35
+    if $need_restore
689f35
+    then
689f35
+	need_restore=false
689f35
+	_restore_config $PCP_SYSCONF_DIR/labels
689f35
+	_sighup_pmcd
689f35
+    fi
689f35
+    $sudo rm -rf $tmp $tmp.*
689f35
+}
689f35
+
689f35
+status=1	# failure is the default!
689f35
+need_restore=false
689f35
+username=`id -u -n`
689f35
+$sudo rm -rf $tmp $tmp.* $seq.full
689f35
+trap "_cleanup; exit \$status" 0 1 2 3 15
689f35
+
689f35
+_check_empty()
689f35
+{
689f35
+    tee -a $seq.full > $tmp.unfiltered
689f35
+    if [ -s $tmp.unfiltered ]
689f35
+    then
689f35
+	echo "Botch: got output from curl"
689f35
+    else
689f35
+	echo "Good!, empty output from curl"
689f35
+    fi
689f35
+}
689f35
+
689f35
+_filter_json()
689f35
+{
689f35
+    tee -a $seq.full > $tmp.unfiltered
689f35
+    if [ -s $tmp.unfiltered ]
689f35
+    then
689f35
+	pmjson < $tmp.unfiltered > $tmp.filtered
689f35
+	status=$?
689f35
+	    if [ $status -eq 0 ]; then
689f35
+	    cat $tmp.filtered | \
689f35
+	    sed \
689f35
+		-e '/"machineid": .*/d' \
689f35
+		-e 's,"series": .*,"series": "SERIES",g' \
689f35
+		-e 's,"context": .*,"context": "CONTEXT",g' \
689f35
+		-e 's,"hostname": .*,"hostname": "HOSTNAME",g' \
689f35
+		-e 's,"domainname": .*,"domainname": "DOMAINNAME",g' \
689f35
+	    #end
689f35
+	else
689f35
+	    echo "Invalid JSON: $status"
689f35
+	    cat $tmp.unfiltered
689f35
+	    rm -f $tmp.context
689f35
+	fi
689f35
+    else
689f35
+	echo "Botch: no output from curl"
689f35
+    fi
689f35
+}
689f35
+
689f35
+_filter_port()
689f35
+{
689f35
+    sed \
689f35
+        -e '/ ipv6 /d' \
689f35
+	-e "s/ $port / PORT /g" \
689f35
+    #end
689f35
+}
689f35
+
689f35
+# real QA test starts here
689f35
+_save_config $PCP_SYSCONF_DIR/labels
689f35
+need_restore=true
689f35
+
689f35
+$sudo rm -rf $PCP_SYSCONF_DIR/labels/*
689f35
+_sighup_pmcd
689f35
+
689f35
+openssl req \
689f35
+	-new -newkey rsa:4096 -days 365 -nodes -x509 \
689f35
+	-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.pcpqa.com" \
689f35
+	-keyout $tmp.key -out $tmp.cert >$seq.full 2>&1
689f35
+# creates a self-signed (insecure) certificate, so for testing only
689f35
+
689f35
+echo "[pmproxy]" >> $tmp.conf
689f35
+echo "pcp.enabled = true" >> $tmp.conf
689f35
+echo "http.enabled = true" >> $tmp.conf
689f35
+echo "redis.enabled = false" >> $tmp.conf
689f35
+echo "secure.enabled = false" >> $tmp.conf
689f35
+
689f35
+port=`_find_free_port`
689f35
+mkdir -p $tmp.pmproxy/pmproxy
689f35
+export PCP_RUN_DIR=$tmp.pmproxy
689f35
+export PCP_TMP_DIR=$tmp.pmproxy
689f35
+
689f35
+$_valgrind_clean_assert pmproxy -f -l- --timeseries \
689f35
+	-c $tmp.conf -p $port -U $username \
689f35
+	>$tmp.valout 2>$tmp.valerr &
689f35
+pid=$!
689f35
+
689f35
+echo "valgrind pid: $pid" >>$seq.full
689f35
+echo "pmproxy port: $port" >>$seq.full
689f35
+
689f35
+# valgrind takes awhile to fire up
689f35
+i=0
689f35
+while [ $i -lt 40 ]
689f35
+do
689f35
+    $PCP_BINADM_DIR/telnet-probe -c localhost $port && break
689f35
+    sleep 1
689f35
+    i=`expr $i + 1`
689f35
+done
689f35
+if $PCP_BINADM_DIR/telnet-probe -c localhost $port
689f35
+then
689f35
+    echo "Startup took $i secs" >>$seq.full
689f35
+else
689f35
+    echo "Arrgh: valgrind failed start pmproxy and get port $port ready after 30 secs"
689f35
+    exit
689f35
+fi
689f35
+
689f35
+date >>$seq.full
689f35
+echo "=== checking serial http operation ===" | tee -a $seq.full
689f35
+for i in 1 2 3 4; do
689f35
+    curl -Gs "http://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i
689f35
+done
689f35
+for i in 1 2 3 4; do
689f35
+echo === out$i === | tee -a $seq.full
689f35
+_filter_json < $tmp.out$i
689f35
+done
689f35
+
689f35
+date >>$seq.full
689f35
+echo "=== checking parallel http operation ===" | tee -a $seq.full
689f35
+for i in 1 2 3 4; do
689f35
+    curl -Gs "http://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i & 2>/dev/null eval pid$i=$!
689f35
+done
689f35
+wait $pid1 $pid2 $pid3 $pid4
689f35
+for i in 1 2 3 4; do
689f35
+echo === out$i === | tee -a $seq.full
689f35
+_filter_json < $tmp.out$i
689f35
+done
689f35
+
689f35
+date >>$seq.full
689f35
+echo "=== checking serial https/TLS operation ===" | tee -a $seq.full
689f35
+for i in 1 2 3 4; do
689f35
+    curl -k -Gs "https://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i
689f35
+done
689f35
+for i in 1 2 3 4; do
689f35
+echo === out$i === | tee -a $seq.full
689f35
+_check_empty < $tmp.out$i
689f35
+done
689f35
+
689f35
+date >>$seq.full
689f35
+echo "=== checking parallel https/TLS operation ===" | tee -a $seq.full
689f35
+for i in 1 2 3 4; do
689f35
+    curl -k -Gs "https://localhost:$port/pmapi/metric?name=sample.long.ten" 2>$tmp.err$i >$tmp.out$i & 2>/dev/null eval pid$i=$!
689f35
+done
689f35
+wait $pid1 $pid2 $pid3 $pid4
689f35
+for i in 1 2 3 4; do
689f35
+echo === out$i === | tee -a $seq.full
689f35
+_check_empty < $tmp.out$i
689f35
+done
689f35
+
689f35
+echo "=== check pmproxy is running ==="
689f35
+pminfo -v -h localhost@localhost:$port hinv.ncpu
689f35
+if [ $? -eq 0 ]; then
689f35
+    echo "pmproxy check passed"
689f35
+else
689f35
+    echo "pmproxy check failed"
689f35
+fi
689f35
+
689f35
+# valgrind takes awhile to shutdown too
689f35
+pmsignal $pid >/dev/null 2>&1
689f35
+pmsleep 3.5
689f35
+echo "=== valgrind stdout ===" | tee -a $seq.full
689f35
+cat $tmp.valout | _filter_valgrind
689f35
+
689f35
+echo "=== valgrind stderr ===" | tee -a $seq.full
689f35
+cat $tmp.valerr | _filter_pmproxy_log | _filter_port
689f35
+
689f35
+# final kill if it's spinning
689f35
+$sudo kill -9 $pid >/dev/null 2>&1
689f35
+
689f35
+# success, all done
689f35
+status=0
689f35
+exit
689f35
diff -Naurp pcp-5.3.5.orig/qa/1458.out pcp-5.3.5/qa/1458.out
689f35
--- pcp-5.3.5.orig/qa/1458.out	1970-01-01 10:00:00.000000000 +1000
689f35
+++ pcp-5.3.5/qa/1458.out	2021-12-09 11:25:01.973327231 +1100
689f35
@@ -0,0 +1,221 @@
689f35
+QA output created by 1458
689f35
+=== checking serial http operation ===
689f35
+=== out1 ===
689f35
+{
689f35
+    "context": "CONTEXT"
689f35
+    "metrics": [
689f35
+        {
689f35
+            "name": "sample.long.ten",
689f35
+            "series": "SERIES"
689f35
+            "pmid": "29.0.11",
689f35
+            "type": "32",
689f35
+            "sem": "instant",
689f35
+            "units": "none",
689f35
+            "labels": {
689f35
+                "agent": "sample",
689f35
+                "cluster": "zero",
689f35
+                "domainname": "DOMAINNAME"
689f35
+                "hostname": "HOSTNAME"
689f35
+                "role": "testing"
689f35
+            },
689f35
+            "text-oneline": "10 as a 32-bit integer",
689f35
+            "text-help": "10 as a 32-bit integer"
689f35
+        }
689f35
+    ]
689f35
+}
689f35
+=== out2 ===
689f35
+{
689f35
+    "context": "CONTEXT"
689f35
+    "metrics": [
689f35
+        {
689f35
+            "name": "sample.long.ten",
689f35
+            "series": "SERIES"
689f35
+            "pmid": "29.0.11",
689f35
+            "type": "32",
689f35
+            "sem": "instant",
689f35
+            "units": "none",
689f35
+            "labels": {
689f35
+                "agent": "sample",
689f35
+                "cluster": "zero",
689f35
+                "domainname": "DOMAINNAME"
689f35
+                "hostname": "HOSTNAME"
689f35
+                "role": "testing"
689f35
+            },
689f35
+            "text-oneline": "10 as a 32-bit integer",
689f35
+            "text-help": "10 as a 32-bit integer"
689f35
+        }
689f35
+    ]
689f35
+}
689f35
+=== out3 ===
689f35
+{
689f35
+    "context": "CONTEXT"
689f35
+    "metrics": [
689f35
+        {
689f35
+            "name": "sample.long.ten",
689f35
+            "series": "SERIES"
689f35
+            "pmid": "29.0.11",
689f35
+            "type": "32",
689f35
+            "sem": "instant",
689f35
+            "units": "none",
689f35
+            "labels": {
689f35
+                "agent": "sample",
689f35
+                "cluster": "zero",
689f35
+                "domainname": "DOMAINNAME"
689f35
+                "hostname": "HOSTNAME"
689f35
+                "role": "testing"
689f35
+            },
689f35
+            "text-oneline": "10 as a 32-bit integer",
689f35
+            "text-help": "10 as a 32-bit integer"
689f35
+        }
689f35
+    ]
689f35
+}
689f35
+=== out4 ===
689f35
+{
689f35
+    "context": "CONTEXT"
689f35
+    "metrics": [
689f35
+        {
689f35
+            "name": "sample.long.ten",
689f35
+            "series": "SERIES"
689f35
+            "pmid": "29.0.11",
689f35
+            "type": "32",
689f35
+            "sem": "instant",
689f35
+            "units": "none",
689f35
+            "labels": {
689f35
+                "agent": "sample",
689f35
+                "cluster": "zero",
689f35
+                "domainname": "DOMAINNAME"
689f35
+                "hostname": "HOSTNAME"
689f35
+                "role": "testing"
689f35
+            },
689f35
+            "text-oneline": "10 as a 32-bit integer",
689f35
+            "text-help": "10 as a 32-bit integer"
689f35
+        }
689f35
+    ]
689f35
+}
689f35
+=== checking parallel http operation ===
689f35
+=== out1 ===
689f35
+{
689f35
+    "context": "CONTEXT"
689f35
+    "metrics": [
689f35
+        {
689f35
+            "name": "sample.long.ten",
689f35
+            "series": "SERIES"
689f35
+            "pmid": "29.0.11",
689f35
+            "type": "32",
689f35
+            "sem": "instant",
689f35
+            "units": "none",
689f35
+            "labels": {
689f35
+                "agent": "sample",
689f35
+                "cluster": "zero",
689f35
+                "domainname": "DOMAINNAME"
689f35
+                "hostname": "HOSTNAME"
689f35
+                "role": "testing"
689f35
+            },
689f35
+            "text-oneline": "10 as a 32-bit integer",
689f35
+            "text-help": "10 as a 32-bit integer"
689f35
+        }
689f35
+    ]
689f35
+}
689f35
+=== out2 ===
689f35
+{
689f35
+    "context": "CONTEXT"
689f35
+    "metrics": [
689f35
+        {
689f35
+            "name": "sample.long.ten",
689f35
+            "series": "SERIES"
689f35
+            "pmid": "29.0.11",
689f35
+            "type": "32",
689f35
+            "sem": "instant",
689f35
+            "units": "none",
689f35
+            "labels": {
689f35
+                "agent": "sample",
689f35
+                "cluster": "zero",
689f35
+                "domainname": "DOMAINNAME"
689f35
+                "hostname": "HOSTNAME"
689f35
+                "role": "testing"
689f35
+            },
689f35
+            "text-oneline": "10 as a 32-bit integer",
689f35
+            "text-help": "10 as a 32-bit integer"
689f35
+        }
689f35
+    ]
689f35
+}
689f35
+=== out3 ===
689f35
+{
689f35
+    "context": "CONTEXT"
689f35
+    "metrics": [
689f35
+        {
689f35
+            "name": "sample.long.ten",
689f35
+            "series": "SERIES"
689f35
+            "pmid": "29.0.11",
689f35
+            "type": "32",
689f35
+            "sem": "instant",
689f35
+            "units": "none",
689f35
+            "labels": {
689f35
+                "agent": "sample",
689f35
+                "cluster": "zero",
689f35
+                "domainname": "DOMAINNAME"
689f35
+                "hostname": "HOSTNAME"
689f35
+                "role": "testing"
689f35
+            },
689f35
+            "text-oneline": "10 as a 32-bit integer",
689f35
+            "text-help": "10 as a 32-bit integer"
689f35
+        }
689f35
+    ]
689f35
+}
689f35
+=== out4 ===
689f35
+{
689f35
+    "context": "CONTEXT"
689f35
+    "metrics": [
689f35
+        {
689f35
+            "name": "sample.long.ten",
689f35
+            "series": "SERIES"
689f35
+            "pmid": "29.0.11",
689f35
+            "type": "32",
689f35
+            "sem": "instant",
689f35
+            "units": "none",
689f35
+            "labels": {
689f35
+                "agent": "sample",
689f35
+                "cluster": "zero",
689f35
+                "domainname": "DOMAINNAME"
689f35
+                "hostname": "HOSTNAME"
689f35
+                "role": "testing"
689f35
+            },
689f35
+            "text-oneline": "10 as a 32-bit integer",
689f35
+            "text-help": "10 as a 32-bit integer"
689f35
+        }
689f35
+    ]
689f35
+}
689f35
+=== checking serial https/TLS operation ===
689f35
+=== out1 ===
689f35
+Good!, empty output from curl
689f35
+=== out2 ===
689f35
+Good!, empty output from curl
689f35
+=== out3 ===
689f35
+Good!, empty output from curl
689f35
+=== out4 ===
689f35
+Good!, empty output from curl
689f35
+=== checking parallel https/TLS operation ===
689f35
+=== out1 ===
689f35
+Good!, empty output from curl
689f35
+=== out2 ===
689f35
+Good!, empty output from curl
689f35
+=== out3 ===
689f35
+Good!, empty output from curl
689f35
+=== out4 ===
689f35
+Good!, empty output from curl
689f35
+=== check pmproxy is running ===
689f35
+pmproxy check passed
689f35
+=== valgrind stdout ===
689f35
+=== valgrind stderr ===
689f35
+Log for pmproxy on HOST started DATE
689f35
+
689f35
+pmproxy: PID = PID
689f35
+pmproxy request port(s):
689f35
+  sts fd   port  family address
689f35
+  === ==== ===== ====== =======
689f35
+ok FD unix UNIX_DOMAIN_SOCKET
689f35
+ok FD PORT inet INADDR_ANY
689f35
+[DATE] pmproxy(PID) Info: pmproxy caught SIGTERM
689f35
+[DATE] pmproxy(PID) Info: pmproxy Shutdown
689f35
+
689f35
+Log finished DATE
689f35
diff -Naurp pcp-5.3.5.orig/src/pmproxy/src/pcp.c pcp-5.3.5/src/pmproxy/src/pcp.c
689f35
--- pcp-5.3.5.orig/src/pmproxy/src/pcp.c	2021-09-24 09:33:06.000000000 +1000
689f35
+++ pcp-5.3.5/src/pmproxy/src/pcp.c	2021-12-09 11:22:09.829321418 +1100
689f35
@@ -1,6 +1,6 @@
689f35
 /*
689f35
- * Copyright (c) 2018-2019 Red Hat.
689f35
- * 
689f35
+ * Copyright (c) 2018-2019,2021 Red Hat.
689f35
+ *
689f35
  * This program is free software; you can redistribute it and/or modify it
689f35
  * under the terms of the GNU Lesser General Public License as published
689f35
  * by the Free Software Foundation; either version 2.1 of the License, or
689f35
@@ -19,22 +19,13 @@
689f35
 #define PDU_MAXLENGTH	(MAXHOSTNAMELEN + HEADER_LENGTH + sizeof("65536")-1)
689f35
 
689f35
 static void
689f35
-client_free(struct client *client)
689f35
-{
689f35
-    if (client->u.pcp.hostname)
689f35
-	sdsfree(client->u.pcp.hostname);
689f35
-    if (client->buffer)
689f35
-	sdsfree(client->buffer);
689f35
-}
689f35
-
689f35
-static void
689f35
 on_server_close(uv_handle_t *handle)
689f35
 {
689f35
     struct client	*client = (struct client *)handle;
689f35
 
689f35
     if (pmDebugOptions.pdu)
689f35
 	fprintf(stderr, "client %p pmcd connection closed\n", client);
689f35
-    client_free(client);
689f35
+    client_put(client);
689f35
 }
689f35
 
689f35
 static void
689f35
@@ -92,12 +83,11 @@ on_server_read(uv_stream_t *stream, ssiz
689f35
 void
689f35
 on_pcp_client_close(struct client *client)
689f35
 {
689f35
-    if (client->u.pcp.connected) {
689f35
+    if (client->u.pcp.connected)
689f35
 	uv_close((uv_handle_t *)&client->u.pcp.socket, on_server_close);
689f35
-	memset(&client->u.pcp, 0, sizeof(client->u.pcp));
689f35
-    } else {
689f35
-	client_free(client);
689f35
-    }
689f35
+    if (client->u.pcp.hostname)
689f35
+	sdsfree(client->u.pcp.hostname);
689f35
+    memset(&client->u.pcp, 0, sizeof(client->u.pcp));
689f35
 }
689f35
 
689f35
 static void
689f35
@@ -118,6 +108,8 @@ on_pcp_client_connect(uv_connect_t *conn
689f35
 
689f35
     /* socket connection to pmcd successfully established */
689f35
     client->u.pcp.state = PCP_PROXY_SETUP;
689f35
+    client->u.pcp.connected = 1;
689f35
+    client_get(client);
689f35
 
689f35
     /* if we have already received PDUs, send them on now */
689f35
     if ((buffer = client->buffer) != NULL) {
689f35
diff -Naurp pcp-5.3.5.orig/src/pmproxy/src/secure.c pcp-5.3.5/src/pmproxy/src/secure.c
689f35
--- pcp-5.3.5.orig/src/pmproxy/src/secure.c	2021-11-01 13:02:26.000000000 +1100
689f35
+++ pcp-5.3.5/src/pmproxy/src/secure.c	2021-12-09 11:22:09.831321384 +1100
689f35
@@ -1,5 +1,5 @@
689f35
 /*
689f35
- * Copyright (c) 2019 Red Hat.
689f35
+ * Copyright (c) 2019,2021 Red Hat.
689f35
  *
689f35
  * This program is free software; you can redistribute it and/or modify it
689f35
  * under the terms of the GNU Lesser General Public License as published
689f35
@@ -16,7 +16,7 @@
689f35
 #include <openssl/opensslv.h>
689f35
 #include <openssl/ssl.h>
689f35
 
689f35
-/* called with proxy->mutex locked */
689f35
+/* called with proxy->write_mutex locked */
689f35
 static void
689f35
 remove_connection_from_queue(struct client *client)
689f35
 {
689f35
@@ -44,9 +44,9 @@ on_secure_client_close(struct client *cl
689f35
     if (pmDebugOptions.auth || pmDebugOptions.http)
689f35
 	fprintf(stderr, "%s: client %p\n", "on_secure_client_close", client);
689f35
 
689f35
-    uv_mutex_lock(&client->proxy->mutex);
689f35
+    uv_mutex_lock(&client->proxy->write_mutex);
689f35
     remove_connection_from_queue(client);
689f35
-    uv_mutex_unlock(&client->proxy->mutex);
689f35
+    uv_mutex_unlock(&client->proxy->write_mutex);
689f35
     /* client->read and client->write freed by SSL_free */
689f35
     SSL_free(client->secure.ssl);
689f35
 }
689f35
@@ -63,7 +63,7 @@ maybe_flush_ssl(struct proxy *proxy, str
689f35
 	client->secure.pending.writes_count > 0)
689f35
 	return;
689f35
 
689f35
-    uv_mutex_lock(&proxy->mutex);
689f35
+    uv_mutex_lock(&proxy->write_mutex);
689f35
     if (proxy->pending_writes == NULL) {
689f35
     	proxy->pending_writes = client;
689f35
 	client->secure.pending.prev = client->secure.pending.next = NULL;
689f35
@@ -75,7 +75,7 @@ maybe_flush_ssl(struct proxy *proxy, str
689f35
 	client->secure.pending.prev = c;
689f35
     }
689f35
     client->secure.pending.queued = 1;
689f35
-    uv_mutex_unlock(&proxy->mutex);
689f35
+    uv_mutex_unlock(&proxy->write_mutex);
689f35
 }
689f35
 
689f35
 static void
689f35
@@ -161,7 +161,7 @@ flush_secure_module(struct proxy *proxy)
689f35
     size_t		i, used;
689f35
     int			sts;
689f35
 
689f35
-    uv_mutex_lock(&proxy->mutex);
689f35
+    uv_mutex_lock(&proxy->write_mutex);
689f35
     head = &proxy->pending_writes;
689f35
     while ((client = *head) != NULL) {
689f35
 	flush_ssl_buffer(client);
689f35
@@ -212,7 +212,7 @@ flush_secure_module(struct proxy *proxy)
689f35
 		    sizeof(uv_buf_t) * client->secure.pending.writes_count);
689f35
 	}
689f35
     }
689f35
-    uv_mutex_unlock(&proxy->mutex);
689f35
+    uv_mutex_unlock(&proxy->write_mutex);
689f35
 }
689f35
 
689f35
 void
689f35
@@ -221,7 +221,8 @@ secure_client_write(struct client *clien
689f35
     struct proxy	*proxy = client->proxy;
689f35
     uv_buf_t		*dup;
689f35
     size_t		count, bytes;
689f35
-    int			i, sts, defer = 0, maybe = 0;
689f35
+    unsigned int	i;
689f35
+    int			sts, defer = 0, maybe = 0;
689f35
 
689f35
     for (i = 0; i < request->nbuffers; i++) {
689f35
 	if (defer == 0) {
689f35
diff -Naurp pcp-5.3.5.orig/src/pmproxy/src/server.c pcp-5.3.5/src/pmproxy/src/server.c
689f35
--- pcp-5.3.5.orig/src/pmproxy/src/server.c	2021-11-01 13:02:26.000000000 +1100
689f35
+++ pcp-5.3.5/src/pmproxy/src/server.c	2021-12-09 11:22:09.831321384 +1100
689f35
@@ -1,5 +1,5 @@
689f35
 /*
689f35
- * Copyright (c) 2018-2019 Red Hat.
689f35
+ * Copyright (c) 2018-2019,2021 Red Hat.
689f35
  *
689f35
  * This program is free software; you can redistribute it and/or modify it
689f35
  * under the terms of the GNU Lesser General Public License as published
689f35
@@ -125,7 +125,7 @@ server_init(int portcount, const char *l
689f35
 			pmGetProgname());
689f35
 	return NULL;
689f35
     }
689f35
-    uv_mutex_init(&proxy->mutex);
689f35
+    uv_mutex_init(&proxy->write_mutex);
689f35
 
689f35
     count = portcount + (*localpath ? 1 : 0);
689f35
     if (count) {
689f35
@@ -229,7 +229,6 @@ void
689f35
 client_put(struct client *client)
689f35
 {
689f35
     unsigned int	refcount;
689f35
-    struct proxy	*proxy = client->proxy;
689f35
 
689f35
     uv_mutex_lock(&client->mutex);
689f35
     assert(client->refcount);
689f35
@@ -237,22 +236,16 @@ client_put(struct client *client)
689f35
     uv_mutex_unlock(&client->mutex);
689f35
 
689f35
     if (refcount == 0) {
689f35
-	/* remove client from the doubly-linked list */
689f35
-	uv_mutex_lock(&proxy->mutex);
689f35
-	if (client->next != NULL)
689f35
-	    client->next->prev = client->prev;
689f35
-	*client->prev = client->next;
689f35
-	uv_mutex_unlock(&proxy->mutex);
689f35
-
689f35
 	if (client->protocol & STREAM_PCP)
689f35
 	    on_pcp_client_close(client);
689f35
 	if (client->protocol & STREAM_HTTP)
689f35
 	    on_http_client_close(client);
689f35
 	if (client->protocol & STREAM_REDIS)
689f35
 	    on_redis_client_close(client);
689f35
-	if (client->protocol & STREAM_SECURE)
689f35
+	if ((client->protocol & STREAM_SECURE) && client->stream.secure)
689f35
 	    on_secure_client_close(client);
689f35
-
689f35
+	if (client->buffer)
689f35
+	    sdsfree(client->buffer);
689f35
 	memset(client, 0, sizeof(*client));
689f35
 	free(client);
689f35
     }
689f35
@@ -284,7 +277,7 @@ on_client_write(uv_write_t *writer, int
689f35
 			"on_client_write", status, client);
689f35
 
689f35
     if (status == 0) {
689f35
-	if (client->protocol & STREAM_SECURE)
689f35
+	if ((client->protocol & STREAM_SECURE) && client->stream.secure)
689f35
 	    on_secure_client_write(client);
689f35
 	if (client->protocol & STREAM_PCP)
689f35
 	    on_pcp_client_write(client);
689f35
@@ -434,10 +427,16 @@ on_client_read(uv_stream_t *stream, ssiz
689f35
     if (nread > 0) {
689f35
 	if (client->protocol == STREAM_UNKNOWN)
689f35
 	    client->protocol |= client_protocol(*buf->base);
689f35
-	if (client->protocol & STREAM_SECURE)
689f35
+
689f35
+#ifdef HAVE_OPENSSL
689f35
+	if ((client->protocol & STREAM_SECURE) && (proxy->ssl != NULL))
689f35
 	    on_secure_client_read(proxy, client, nread, buf);
689f35
 	else
689f35
 	    on_protocol_read(stream, nread, buf);
689f35
+#else
689f35
+	on_protocol_read(stream, nread, buf);
689f35
+#endif
689f35
+
689f35
     } else if (nread < 0) {
689f35
 	if (pmDebugOptions.af)
689f35
 	    fprintf(stderr, "%s: read error %ld "
689f35
@@ -494,14 +493,6 @@ on_client_connection(uv_stream_t *stream
689f35
     handle->data = (void *)proxy;
689f35
     client->proxy = proxy;
689f35
 
689f35
-    /* insert client into doubly-linked list at the head */
689f35
-    uv_mutex_lock(&proxy->mutex);
689f35
-    if ((client->next = proxy->first) != NULL)
689f35
-	proxy->first->prev = &client->next;
689f35
-    proxy->first = client;
689f35
-    client->prev = &proxy->first;
689f35
-    uv_mutex_unlock(&proxy->mutex);
689f35
-
689f35
     status = uv_read_start((uv_stream_t *)&client->stream.u.tcp,
689f35
 			    on_buffer_alloc, on_client_read);
689f35
     if (status != 0) {
689f35
@@ -719,7 +710,7 @@ shutdown_ports(void *arg)
689f35
     struct proxy	*proxy = (struct proxy *)arg;
689f35
     struct server	*server;
689f35
     struct stream	*stream;
689f35
-    int			i;
689f35
+    unsigned int	i;
689f35
 
689f35
     for (i = 0; i < proxy->nservers; i++) {
689f35
 	server = &proxy->servers[i];
689f35
@@ -756,7 +747,8 @@ dump_request_ports(FILE *output, void *a
689f35
     struct proxy	*proxy = (struct proxy *)arg;
689f35
     struct stream	*stream;
689f35
     uv_os_fd_t		uv_fd;
689f35
-    int			i, fd;
689f35
+    unsigned int	i;
689f35
+    int			fd;
689f35
 
689f35
     fprintf(output, "%s request port(s):\n"
689f35
 		"  sts fd   port  family address\n"
689f35
diff -Naurp pcp-5.3.5.orig/src/pmproxy/src/server.h pcp-5.3.5/src/pmproxy/src/server.h
689f35
--- pcp-5.3.5.orig/src/pmproxy/src/server.h	2021-09-24 09:33:06.000000000 +1000
689f35
+++ pcp-5.3.5/src/pmproxy/src/server.h	2021-12-09 11:22:09.830321401 +1100
689f35
@@ -1,5 +1,5 @@
689f35
 /*
689f35
- * Copyright (c) 2018-2019 Red Hat.
689f35
+ * Copyright (c) 2018-2019,2021 Red Hat.
689f35
  *
689f35
  * This program is free software; you can redistribute it and/or modify it
689f35
  * under the terms of the GNU Lesser General Public License as published
689f35
@@ -97,11 +97,11 @@ typedef struct http_client {
689f35
 
689f35
 typedef struct pcp_client {
689f35
     pcp_proxy_state_t	state;
689f35
-    sds			hostname;
689f35
     unsigned int	port : 16;
689f35
     unsigned int	certreq : 1;
689f35
     unsigned int	connected : 1;
689f35
     unsigned int	pad : 14;
689f35
+    sds			hostname;
689f35
     uv_connect_t	pmcd;
689f35
     uv_tcp_t		socket;
689f35
 } pcp_client_t;
689f35
@@ -136,8 +136,6 @@ typedef struct client {
689f35
 	pcp_client_t	pcp;
689f35
     } u;
689f35
     struct proxy	*proxy;
689f35
-    struct client	*next;
689f35
-    struct client	**prev;
689f35
     sds			buffer;
689f35
 } client_t;
689f35
 
689f35
@@ -161,7 +159,7 @@ typedef struct proxy {
689f35
     struct dict		*config;	/* configuration dictionary */
689f35
     uv_loop_t		*events;	/* global, async event loop */
689f35
     uv_callback_t	write_callbacks;
689f35
-    uv_mutex_t		mutex;		/* protects client lists and pending writes */
689f35
+    uv_mutex_t		write_mutex;	/* protects pending writes */
689f35
 } proxy_t;
689f35
 
689f35
 extern void proxylog(pmLogLevel, sds, void *);