<feed xmlns='http://www.w3.org/2005/Atom'>
<title>nginx.git/src/core/ngx_buf.c, branch release-1.30.0</title>
<subtitle>nginx</subtitle>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/'/>
<entry>
<title>Changed ngx_chain_update_chains() to test tag first (ticket #2248).</title>
<updated>2021-10-29T23:39:19+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-10-29T23:39:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=2c8dd1c33e19842fcf1e87b53cb86aeeea094dda'/>
<id>2c8dd1c33e19842fcf1e87b53cb86aeeea094dda</id>
<content type='text'>
Without this change, aio used with HTTP/2 can result in connection hang,
as observed with "aio threads; aio_write on;" and proxying (ticket #2248).

The problem is that HTTP/2 updates buffers outside of the output filters
(notably, marks them as sent), and then posts a write event to call
output filters.  If a filter does not call the next one for some reason
(for example, because of an AIO operation in progress), this might
result in a state when the owner of a buffer already called
ngx_chain_update_chains() and can reuse the buffer, while the same buffer
is still sitting in the busy chain of some other filter.

In the particular case a buffer was sitting in output chain's ctx-&gt;busy,
and was reused by event pipe.  Output chain's ctx-&gt;busy was permanently
blocked by it, and this resulted in connection hang.

Fix is to change ngx_chain_update_chains() to skip buffers from other
modules unconditionally, without trying to wait for these buffers to
become empty.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Without this change, aio used with HTTP/2 can result in connection hang,
as observed with "aio threads; aio_write on;" and proxying (ticket #2248).

The problem is that HTTP/2 updates buffers outside of the output filters
(notably, marks them as sent), and then posts a write event to call
output filters.  If a filter does not call the next one for some reason
(for example, because of an AIO operation in progress), this might
result in a state when the owner of a buffer already called
ngx_chain_update_chains() and can reuse the buffer, while the same buffer
is still sitting in the busy chain of some other filter.

In the particular case a buffer was sitting in output chain's ctx-&gt;busy,
and was reused by event pipe.  Output chain's ctx-&gt;busy was permanently
blocked by it, and this resulted in connection hang.

Fix is to change ngx_chain_update_chains() to skip buffers from other
modules unconditionally, without trying to wait for these buffers to
become empty.
</pre>
</div>
</content>
</entry>
<entry>
<title>Leave chain in ngx_chain_add_copy() in consistent state on errors.</title>
<updated>2018-06-04T15:47:54+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2018-06-04T15:47:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=dac90a4bff8404e8097249a1ee444b77580f43ba'/>
<id>dac90a4bff8404e8097249a1ee444b77580f43ba</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fixed trailer construction with limit on FreeBSD and macOS.</title>
<updated>2017-01-20T18:12:48+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2017-01-20T18:12:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=7ca4b6743d3bcbce1d2a1f024af406afe3c26025'/>
<id>7ca4b6743d3bcbce1d2a1f024af406afe3c26025</id>
<content type='text'>
The ngx_chain_coalesce_file() function may produce more bytes to send then
requested in the limit passed, as it aligns the last file position
to send to memory page boundary.  As a result, (limit - send) may become
negative.  This resulted in big positive number when converted to size_t
while calling ngx_output_chain_to_iovec().

Another part of the problem is in ngx_chain_coalesce_file(): it changes cl
to the next chain link even if the current buffer is only partially sent
due to limit.

Therefore, if a file buffer was not expected to be fully sent due to limit,
and was followed by a memory buffer, nginx called sendfile() with a part
of the file buffer, and the memory buffer in trailer.  If there were enough
room in the socket buffer, this resulted in a part of the file buffer being
skipped, and corresponding part of the memory buffer sent instead.

The bug was introduced in 8e903522c17a (1.7.8).  Configurations affected
are ones using limits, that is, limit_rate and/or sendfile_max_chunk, and
memory buffers after file ones (may happen when using subrequests or
with proxying with disk buffering).

Fix is to explicitly check if (send &lt; limit) before constructing trailer
with ngx_output_chain_to_iovec().  Additionally, ngx_chain_coalesce_file()
was modified to preserve unfinished file buffers in cl.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The ngx_chain_coalesce_file() function may produce more bytes to send then
requested in the limit passed, as it aligns the last file position
to send to memory page boundary.  As a result, (limit - send) may become
negative.  This resulted in big positive number when converted to size_t
while calling ngx_output_chain_to_iovec().

Another part of the problem is in ngx_chain_coalesce_file(): it changes cl
to the next chain link even if the current buffer is only partially sent
due to limit.

Therefore, if a file buffer was not expected to be fully sent due to limit,
and was followed by a memory buffer, nginx called sendfile() with a part
of the file buffer, and the memory buffer in trailer.  If there were enough
room in the socket buffer, this resulted in a part of the file buffer being
skipped, and corresponding part of the memory buffer sent instead.

The bug was introduced in 8e903522c17a (1.7.8).  Configurations affected
are ones using limits, that is, limit_rate and/or sendfile_max_chunk, and
memory buffers after file ones (may happen when using subrequests or
with proxying with disk buffering).

Fix is to explicitly check if (send &lt; limit) before constructing trailer
with ngx_output_chain_to_iovec().  Additionally, ngx_chain_coalesce_file()
was modified to preserve unfinished file buffers in cl.
</pre>
</div>
</content>
</entry>
<entry>
<title>Core: slight optimization in ngx_chain_update_chains().</title>
<updated>2016-11-10T02:17:53+00:00</updated>
<author>
<name>hucongcong</name>
<email>hucong.c@foxmail.com</email>
</author>
<published>2016-11-10T02:17:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=42298aeb13040cc94026a2d405726895fb19b1e0'/>
<id>42298aeb13040cc94026a2d405726895fb19b1e0</id>
<content type='text'>
It is not necessary to traverse *busy and link the *out when *out is NULL.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It is not necessary to traverse *busy and link the *out when *out is NULL.
</pre>
</div>
</content>
</entry>
<entry>
<title>Moved the code for coalescing file buffers to a separate function.</title>
<updated>2014-08-13T11:11:45+00:00</updated>
<author>
<name>Valentin Bartenev</name>
<email>vbart@nginx.com</email>
</author>
<published>2014-08-13T11:11:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=d85d459bb2bfd147ea003310369d42c8891c6b39'/>
<id>d85d459bb2bfd147ea003310369d42c8891c6b39</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Renamed ngx_handle_sent_chain() to ngx_chain_update_sent().</title>
<updated>2014-11-19T18:16:19+00:00</updated>
<author>
<name>Valentin Bartenev</name>
<email>vbart@nginx.com</email>
</author>
<published>2014-11-19T18:16:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=41ed9734561fc957a64ca7e4dab5a8c6e3ac3c0b'/>
<id>41ed9734561fc957a64ca7e4dab5a8c6e3ac3c0b</id>
<content type='text'>
No functional changes.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
No functional changes.
</pre>
</div>
</content>
</entry>
<entry>
<title>Moved the code for adjusting sent buffers in a separate function.</title>
<updated>2014-08-13T11:11:45+00:00</updated>
<author>
<name>Valentin Bartenev</name>
<email>vbart@nginx.com</email>
</author>
<published>2014-08-13T11:11:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=4aac91049f8909e928580f9fb8b752ba748f4167'/>
<id>4aac91049f8909e928580f9fb8b752ba748f4167</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Copyright updated.</title>
<updated>2012-01-18T15:07:43+00:00</updated>
<author>
<name>Maxim Konovalov</name>
<email>maxim@nginx.com</email>
</author>
<published>2012-01-18T15:07:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=f8d59e33f34185c28d1d3c6625a897e214b7ca73'/>
<id>f8d59e33f34185c28d1d3c6625a897e214b7ca73</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>API change: ngx_chain_update_chains() now requires pool.</title>
<updated>2011-09-15T16:03:17+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2011-09-15T16:03:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=d7c2673d3ffb5c8c7c994a3ee385997237ed0d99'/>
<id>d7c2673d3ffb5c8c7c994a3ee385997237ed0d99</id>
<content type='text'>
The ngx_chain_update_chains() needs pool to free chain links used for buffers
with non-matching tags.  Providing one helps to reduce memory consumption
for long-lived requests.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The ngx_chain_update_chains() needs pool to free chain links used for buffers
with non-matching tags.  Providing one helps to reduce memory consumption
for long-lived requests.
</pre>
</div>
</content>
</entry>
<entry>
<title>remove never used zero copy stuff</title>
<updated>2008-12-17T20:47:18+00:00</updated>
<author>
<name>Igor Sysoev</name>
<email>igor@sysoev.ru</email>
</author>
<published>2008-12-17T20:47:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=ed9b6d8962c6b7cf0546d0b2d69f34c879395757'/>
<id>ed9b6d8962c6b7cf0546d0b2d69f34c879395757</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
</feed>
