summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordberg.se>2013-11-18 17:27:23 +0100
committerLinus Nordberg <linus@nordberg.se>2013-11-18 17:27:23 +0100
commit049e72ddaa0cd24fce2d7550e604fc47ec7f9b3b (patch)
treea9ad621349a19387013b4aae143c9872d3bd46ae
parent1f84470aaf49264084d39078adb4afd26d0b4d71 (diff)
Avoid leaking memory when receiving a bad response.
A badly authenticated response message or one that didn't decode or decrypt correctly was never freed. If caller didn't pass pkt_out, any response was leaked as well. As a bonus, the code is now readable too.
-rw-r--r--lib/conn.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/lib/conn.c b/lib/conn.c
index 499c330..970a071 100644
--- a/lib/conn.c
+++ b/lib/conn.c
@@ -307,20 +307,23 @@ rs_conn_receive_packet (struct rs_connection *conn,
evutil_gai_strerror (err));
rs_debug (("%s: event loop done\n", __func__));
- if ((pkt->flags & RS_PACKET_RECEIVED) == 0
- || (req_msg
- && packet_verify_response (pkt->conn, pkt, req_msg) != RSE_OK))
+ if ((pkt->flags & RS_PACKET_RECEIVED) != 0)
{
- if (rs_err_conn_peek_code (pkt->conn) == RSE_OK)
- /* No packet and no error on the stack _should_ mean that the
- server hung up on us. */
- rs_err_conn_push (pkt->conn, RSE_DISCO, "no response");
- return rs_err_conn_peek_code (conn);
+ /* If the caller passed a request, check the response. */
+ if (req_msg)
+ err = packet_verify_response (pkt->conn, pkt, req_msg);
+
+ /* If the response was OK and the caller wants it, hand it
+ over, else free it. */
+ if (err == RSE_OK && pkt_out)
+ *pkt_out = pkt;
+ else
+ rs_packet_destroy (pkt);
}
+ else
+ err = rs_err_conn_peek_code (pkt->conn);
- if (pkt_out)
- *pkt_out = pkt;
- return RSE_OK;
+ return err;
}
void