diff options
author | Linus Nordberg <linus@nordberg.se> | 2013-11-18 17:27:23 +0100 |
---|---|---|
committer | Linus Nordberg <linus@nordberg.se> | 2013-11-18 17:27:23 +0100 |
commit | 049e72ddaa0cd24fce2d7550e604fc47ec7f9b3b (patch) | |
tree | a9ad621349a19387013b4aae143c9872d3bd46ae /lib/conn.c | |
parent | 1f84470aaf49264084d39078adb4afd26d0b4d71 (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.
Diffstat (limited to 'lib/conn.c')
-rw-r--r-- | lib/conn.c | 25 |
1 files changed, 14 insertions, 11 deletions
@@ -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 |