mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
BUG/MEDIUM: dns: Properly handle error when a response consumed
When a response is consumed, result for co_getblk() is never checked. It seems ok because amount of output data is always checked first. But There is an issue when we try to get the first 2 bytes to read the message length. If there is only one byte followed by a shutdown, the applet ignore the shutdown and loop till the timeout to get more data. So to avoid any issue and improve shutdown detection, the co_getblk() return value is always tested. In addition, if there is not enough data, the applet explicitly ask for more data by calling applet_need_more_data(). This patch relies on the previous one: * BUG/MEDIUM: channel: Improve reports for shut in co_getblk() Both should be backported as far as 2.4. On 2.5 and 2.4, applet_need_more_data() must be replaced by si_rx_endp_more().
This commit is contained in:
parent
5f5c94617e
commit
28975e1e10
36
src/dns.c
36
src/dns.c
@ -661,30 +661,35 @@ read:
|
||||
struct dns_query *query;
|
||||
|
||||
if (!ds->rx_msg.len) {
|
||||
/* next message len is not fully available into the channel */
|
||||
if (co_data(sc_oc(sc)) < 2)
|
||||
break;
|
||||
|
||||
/* retrieve message len */
|
||||
co_getblk(sc_oc(sc), (char *)&msg_len, 2, 0);
|
||||
ret = co_getblk(sc_oc(sc), (char *)&msg_len, 2, 0);
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
goto close;
|
||||
applet_need_more_data(appctx);
|
||||
break;
|
||||
}
|
||||
|
||||
/* mark as consumed */
|
||||
co_skip(sc_oc(sc), 2);
|
||||
|
||||
/* store message len */
|
||||
ds->rx_msg.len = ntohs(msg_len);
|
||||
}
|
||||
|
||||
if (!co_data(sc_oc(sc))) {
|
||||
/* we need more data but nothing is available */
|
||||
break;
|
||||
if (!ds->rx_msg.len)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (co_data(sc_oc(sc)) + ds->rx_msg.offset < ds->rx_msg.len) {
|
||||
/* message only partially available */
|
||||
|
||||
/* read available data */
|
||||
co_getblk(sc_oc(sc), ds->rx_msg.area + ds->rx_msg.offset, co_data(sc_oc(sc)), 0);
|
||||
ret = co_getblk(sc_oc(sc), ds->rx_msg.area + ds->rx_msg.offset, co_data(sc_oc(sc)), 0);
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
goto close;
|
||||
applet_need_more_data(appctx);
|
||||
break;
|
||||
}
|
||||
|
||||
/* update message offset */
|
||||
ds->rx_msg.offset += co_data(sc_oc(sc));
|
||||
@ -693,13 +698,20 @@ read:
|
||||
co_skip(sc_oc(sc), co_data(sc_oc(sc)));
|
||||
|
||||
/* we need to wait for more data */
|
||||
applet_need_more_data(appctx);
|
||||
break;
|
||||
}
|
||||
|
||||
/* enough data is available into the channel to read the message until the end */
|
||||
|
||||
/* read from the channel until the end of the message */
|
||||
co_getblk(sc_oc(sc), ds->rx_msg.area + ds->rx_msg.offset, ds->rx_msg.len - ds->rx_msg.offset, 0);
|
||||
ret = co_getblk(sc_oc(sc), ds->rx_msg.area + ds->rx_msg.offset, ds->rx_msg.len - ds->rx_msg.offset, 0);
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
goto close;
|
||||
applet_need_more_data(appctx);
|
||||
break;
|
||||
}
|
||||
|
||||
/* consume all data until the end of the message from the channel */
|
||||
co_skip(sc_oc(sc), ds->rx_msg.len - ds->rx_msg.offset);
|
||||
|
Loading…
x
Reference in New Issue
Block a user