transport: Match on response in pldm_transport_send_recv_msg()
pldm_send_recv() does not verify the corrected match of a PLDM response
message with the request message by comparing the Instance ID as
pldm_recv(). This will cause the PLDM command of the pldmtool receives
the response message of the other PLDM command from other services. The
pldm_transport_send_recv_msg() which is called by pldm_send_recv()
method should check the Instance ID of the response to verify the match.
Tested:
1. Run pldmtool while pldmd service continuously polls multiple pldm
sensors.
2. The pldmtool should not be failed with PLDM_ERROR_INVALID_LENGTH
error.
Signed-off-by: Thu Nguyen <thu@os.amperecomputing.com>
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I491db086cf2a0dff1981f2959d1dab936d46d2db
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c3f77af..fccb5bd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,3 +29,4 @@
1. requester: Make pldm_open() return existing fd
2. transport: Prevent sticking in waiting for response
+3. transport: Match on response in pldm_transport_send_recv_msg()
diff --git a/include/libpldm/transport.h b/include/libpldm/transport.h
index e5464b8..7127335 100644
--- a/include/libpldm/transport.h
+++ b/include/libpldm/transport.h
@@ -87,6 +87,11 @@
* @brief Synchronously send a PLDM request and receive the response. Control is
* returned to the caller once the response is received.
*
+ * pldm_transport_send_recv() will discard messages received on the underlying transport instance
+ * that are not a response that matches the request. Do not use this function if you're attempting
+ * to use the transport instance asynchronously, as this discard behaviour will affect other
+ * responses that you may care about.
+ *
* @pre The pldm transport instance must be initialised; otherwise,
* PLDM_REQUESTER_INVALID_SETUP is returned. If the transport requires a
* TID to transport specific identifier mapping, this must already be set
diff --git a/src/transport/transport.c b/src/transport/transport.c
index d4608a7..77a33f8 100644
--- a/src/transport/transport.c
+++ b/src/transport/transport.c
@@ -160,16 +160,19 @@
static const struct timeval max_response_interval = {
.tv_sec = 4, .tv_usec = 800000
};
+ const struct pldm_msg_hdr *req_hdr;
struct timeval remaining;
+ pldm_requester_rc_t rc;
struct timeval now;
struct timeval end;
- pldm_requester_rc_t rc;
int ret;
- if (!resp_msg_len) {
+ if (req_msg_len < sizeof(*req_hdr) || !resp_msg_len) {
return PLDM_REQUESTER_INVALID_SETUP;
}
+ req_hdr = pldm_req_msg;
+
rc = pldm_transport_send_msg(transport, tid, pldm_req_msg, req_msg_len);
if (rc != PLDM_REQUESTER_SUCCESS) {
return rc;
@@ -197,7 +200,13 @@
rc = pldm_transport_recv_msg(transport, tid, pldm_resp_msg,
resp_msg_len);
if (rc == PLDM_REQUESTER_SUCCESS) {
- return rc;
+ const struct pldm_msg_hdr *resp_hdr = *pldm_resp_msg;
+ if (req_hdr->instance_id == resp_hdr->instance_id) {
+ return rc;
+ }
+
+ /* This isn't the message we wanted */
+ free(*pldm_resp_msg);
}
ret = clock_gettimeval(CLOCK_MONOTONIC, &now);