Discussion:
[libmicrohttpd] Regarding Flow control
Santos Das
2018-09-17 14:52:53 UTC
Permalink
Hi,

Could you kindly let me know how can we implement the flow control ?
Protection against the badly behaving clients.


HTTP/1.1 servers SHOULD maintain persistent connections and use TCP's
flow control

mechanisms to resolve temporary overloads, rather than terminating
connections with

the expectation that clients will retry. The latter technique can
exacerbate network

congestion.



https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html


Thanks, Santos
Santos Das
2018-09-17 15:33:25 UTC
Permalink
Hi,

Just to add more, my application is single threaded and I am running MHD
inside that. I don't create additional threads. I use suspend and resume as
suggested earlier as I do async processing.

So, I am thinking how can we implement flow control in this scenario..

Thanks, Santos
Post by Santos Das
Hi,
Could you kindly let me know how can we implement the flow control ?
Protection against the badly behaving clients.
HTTP/1.1 servers SHOULD maintain persistent connections and use TCP's flow control
mechanisms to resolve temporary overloads, rather than terminating connections with
the expectation that clients will retry. The latter technique can exacerbate network
congestion.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Thanks, Santos
Kunal Ekawde
2018-09-17 19:01:13 UTC
Permalink
If the connection is suspended and cases of:
a. client closes the connection before response is sent.
b. server app doesn't respond at all post suspend.

both cases there is no notification by MHD even if connection timeout is
specified and notify callback. How can these cases be handled ?

Thanks,
Kunal
Post by Santos Das
Hi,
Just to add more, my application is single threaded and I am running MHD
inside that. I don't create additional threads. I use suspend and resume as
suggested earlier as I do async processing.
So, I am thinking how can we implement flow control in this scenario..
Thanks, Santos
Post by Santos Das
Hi,
Could you kindly let me know how can we implement the flow control ?
Protection against the badly behaving clients.
HTTP/1.1 servers SHOULD maintain persistent connections and use TCP's flow control
mechanisms to resolve temporary overloads, rather than terminating connections with
the expectation that clients will retry. The latter technique can exacerbate network
congestion.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Thanks, Santos
--
~Kunal
Christian Grothoff
2018-09-18 09:41:58 UTC
Permalink
If you suspend a connection, you are responsible to schedule some job to
resume it, after which MHD's timeout counter will start again (and of
course your response logic could then also just force MHD to close the
connection once MHD asks for response data). MHD timeouts are there to
detect (idle) clients that just keep connections open, not to prevent
the server from suspending a connection.

If the client closes a connection, it'll be detected if/when we try to
send data to the client and handled appropriately.

Happy hacking!

Christian
Post by Kunal Ekawde
a. client closes the connection before response is sent.
b. server app doesn't respond at all post suspend.
 
both cases there is no notification by MHD even if connection timeout is
specified and notify callback. How can these cases be handled ?
Thanks,
Kunal
Hi,
Just to add more, my application is single threaded and I am running
MHD inside that. I don't create additional threads. I use suspend
and resume as suggested earlier as I do async processing.
So, I am thinking how can we implement flow control in this scenario..
Thanks, Santos
Hi,
Could you kindly let me know how can we implement the flow
control ? Protection against the badly behaving clients.
HTTP/1.1 servers SHOULD maintain persistent connections and use TCP's flow control
mechanisms to resolve temporary overloads, rather than terminating connections with
the expectation that clients will retry. The latter technique can exacerbate network
congestion.
 
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Thanks, Santos
--
~Kunal
Kunal Ekawde
2018-09-18 10:23:11 UTC
Permalink
Thanks Christian,
So as a solution we need to have a timer for such cases and on timer expiry
, resume the connection post which as data is not available, either error
respond or close connection. If we close the connection, we shall loose the
pending requests on that connection right ? and if we error respond, we
shall get pending messages on that connection right (number of pending
messages would depend on MHD_OPTION_CONNECTION_MEMORY_LIMIT?) ?
If the case was client side disconnection, post resume, we should get
notify callback with reason 'MHD_REQUEST_TERMINATED_WITH_ERROR' ? so we can
do cleanup right ?

Thanks,
Kunal
Post by Christian Grothoff
If you suspend a connection, you are responsible to schedule some job to
resume it, after which MHD's timeout counter will start again (and of
course your response logic could then also just force MHD to close the
connection once MHD asks for response data). MHD timeouts are there to
detect (idle) clients that just keep connections open, not to prevent
the server from suspending a connection.
If the client closes a connection, it'll be detected if/when we try to
send data to the client and handled appropriately.
Happy hacking!
Christian
Post by Kunal Ekawde
a. client closes the connection before response is sent.
b. server app doesn't respond at all post suspend.
both cases there is no notification by MHD even if connection timeout is
specified and notify callback. How can these cases be handled ?
Thanks,
Kunal
Hi,
Just to add more, my application is single threaded and I am running
MHD inside that. I don't create additional threads. I use suspend
and resume as suggested earlier as I do async processing.
So, I am thinking how can we implement flow control in this
scenario..
Post by Kunal Ekawde
Thanks, Santos
Hi,
Could you kindly let me know how can we implement the flow
control ? Protection against the badly behaving clients.
HTTP/1.1 servers SHOULD maintain persistent connections and use
TCP's flow control
Post by Kunal Ekawde
mechanisms to resolve temporary overloads, rather than
terminating connections with
Post by Kunal Ekawde
the expectation that clients will retry. The latter technique
can exacerbate network
Post by Kunal Ekawde
congestion.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Thanks, Santos
--
~Kunal
--
~Kunal
Christian Grothoff
2018-09-18 11:07:31 UTC
Permalink
Post by Kunal Ekawde
Thanks Christian,
So as a solution we need to have a timer for such cases and on timer
expiry , resume the connection post which as data is not available,
either error respond or close connection.
Yes, basically if you suspend to perform some asynchronous activity that
needs a timeout, you need to manage that timeout.
Post by Kunal Ekawde
If we close the connection, we
shall loose the pending requests on that connection right ?
Yes, if you "close" i.e. by returning "MHD_NO".
Post by Kunal Ekawde
and if we
error respond, we shall get pending messages on that connection right
(number of pending messages would depend on
MHD_OPTION_CONNECTION_MEMORY_LIMIT?)?
If you respond, other requests on the connection will then be processed,
but not limited by the MEMORY_LIMIT. MHD won't use more RAM per
connection than allowed by MEMORY_LIMIT, but the OSes for client and
server negotiate a TCP buffer which is really what limits network
transmissions. And the client just won't be able to transmit more
requests than what that TCP buffer allows until you resume, but in
theory the number of requests that can be pipelined is unlimited.
Post by Kunal Ekawde
If the case was client side disconnection, post resume, we should get
notify callback with reason 'MHD_REQUEST_TERMINATED_WITH_ERROR' ? so we
can do cleanup right ?
Yes.
Kunal Ekawde
2018-09-18 12:22:34 UTC
Permalink
Thanks for prompt response, few more doubts :)
1. Yeah, timers per connection on each request doesn't seems good, need to
figure that out.
2. When you say ' MHD won't use more RAM per connection than allowed by
MEMORY_LIMIT' , will MHD read from TCP buffer only 'MEMORY_LIMIT' data ? is
it the recv call buffer size ? when will remaining data be read ?

Thanks
Post by Christian Grothoff
Post by Kunal Ekawde
Thanks Christian,
So as a solution we need to have a timer for such cases and on timer
expiry , resume the connection post which as data is not available,
either error respond or close connection.
Yes, basically if you suspend to perform some asynchronous activity that
needs a timeout, you need to manage that timeout.
Post by Kunal Ekawde
If we close the connection, we
shall loose the pending requests on that connection right ?
Yes, if you "close" i.e. by returning "MHD_NO".
Post by Kunal Ekawde
and if we
error respond, we shall get pending messages on that connection right
(number of pending messages would depend on
MHD_OPTION_CONNECTION_MEMORY_LIMIT?)?
If you respond, other requests on the connection will then be processed,
but not limited by the MEMORY_LIMIT. MHD won't use more RAM per
connection than allowed by MEMORY_LIMIT, but the OSes for client and
server negotiate a TCP buffer which is really what limits network
transmissions. And the client just won't be able to transmit more
requests than what that TCP buffer allows until you resume, but in
theory the number of requests that can be pipelined is unlimited.
Post by Kunal Ekawde
If the case was client side disconnection, post resume, we should get
notify callback with reason 'MHD_REQUEST_TERMINATED_WITH_ERROR' ? so we
can do cleanup right ?
Yes.
--
~Kunal
Christian Grothoff
2018-09-18 12:25:36 UTC
Permalink
Post by Kunal Ekawde
Thanks for prompt response, few more doubts :)
1. Yeah, timers per connection on each request doesn't seems good, need
to figure that out.
2. When you say ' MHD won't use more RAM per connection than allowed by
MEMORY_LIMIT' , will MHD read from TCP buffer only 'MEMORY_LIMIT' data ?
is it the recv call buffer size ? when will remaining data be read ?
When the application has finished processing the data that was read and
thus created the necessary free space for more.
Santos Das
2018-09-18 11:31:53 UTC
Permalink
Hi Christian,

Thanks a lot. I have few questions in this regard -

a. When we put the connection in suspend state, can we pass a timeout at
the expiry of which the connection will be automatically resumed?

b. For asynchronous communication , i.e the application received the
request but is not able to send the response now (it needs to do some work
may be creating another request to another endpoint) , is it mandatory to
use suspend-resume only or there is some other mechanism that we can use ?

c. How does the keep alive works in the HTTP server library ?

Sorry, lot of questions. But, please see if you could help in this.
Post by Christian Grothoff
If you suspend a connection, you are responsible to schedule some job to
resume it, after which MHD's timeout counter will start again (and of
course your response logic could then also just force MHD to close the
connection once MHD asks for response data). MHD timeouts are there to
detect (idle) clients that just keep connections open, not to prevent
the server from suspending a connection.
If the client closes a connection, it'll be detected if/when we try to
send data to the client and handled appropriately.
Happy hacking!
Christian
Post by Kunal Ekawde
a. client closes the connection before response is sent.
b. server app doesn't respond at all post suspend.
both cases there is no notification by MHD even if connection timeout is
specified and notify callback. How can these cases be handled ?
Thanks,
Kunal
Hi,
Just to add more, my application is single threaded and I am running
MHD inside that. I don't create additional threads. I use suspend
and resume as suggested earlier as I do async processing.
So, I am thinking how can we implement flow control in this
scenario..
Post by Kunal Ekawde
Thanks, Santos
Hi,
Could you kindly let me know how can we implement the flow
control ? Protection against the badly behaving clients.
HTTP/1.1 servers SHOULD maintain persistent connections and use
TCP's flow control
Post by Kunal Ekawde
mechanisms to resolve temporary overloads, rather than
terminating connections with
Post by Kunal Ekawde
the expectation that clients will retry. The latter technique
can exacerbate network
Post by Kunal Ekawde
congestion.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Thanks, Santos
--
~Kunal
Christian Grothoff
2018-09-18 11:57:56 UTC
Permalink
Post by Santos Das
Hi Christian,
Thanks a lot. I have few questions in this regard -
a.    When we put the connection in suspend state, can we pass a timeout
at the expiry of which the connection will be automatically resumed?
No.
Post by Santos Das
b.    For asynchronous communication , i.e the application received the
request but is not able to send the response now (it needs to do some
work may be creating another request to another endpoint) , is it
mandatory to use suspend-resume only or there is some other mechanism
that we can use ?
If you use 'thread per connection', you could also simply block.
Post by Santos Das
c.   How does the keep alive works in the HTTP server library ? 
MHD takes care of it, it adds keep-alive headers and processes them
_unless_ explicitly overridden by the application.
Post by Santos Das
Could you please explain how the TCP's flow control mechanism is
helping in this case. A few lines would be great, please.
TCP flow control requires the kernel to provide message buffers for
retransmission (sender) and reordering (receiver). So those buffers can
and will be used by the kernel (on any OS) if the client sends
additional requests that the server is not yet processing.
Post by Santos Das
Sorry, lot of questions. But, please see if you could help in this.
If you suspend a connection, you are responsible to schedule some job to
resume it, after which MHD's timeout counter will start again (and of
course your response logic could then also just force MHD to close the
connection once MHD asks for response data).  MHD timeouts are there to
detect (idle) clients that just keep connections open, not to prevent
the server from suspending a connection.
If the client closes a connection, it'll be detected if/when we try to
send data to the client and handled appropriately.
Happy hacking!
Christian
Post by Kunal Ekawde
a. client closes the connection before response is sent.
b. server app doesn't respond at all post suspend.
 
both cases there is no notification by MHD even if connection
timeout is
Post by Kunal Ekawde
specified and notify callback. How can these cases be handled ?
Thanks,
Kunal
     Hi,
     Just to add more, my application is single threaded and I am
running
Post by Kunal Ekawde
     MHD inside that. I don't create additional threads. I use suspend
     and resume as suggested earlier as I do async processing.
     So, I am thinking how can we implement flow control in this
scenario..
Post by Kunal Ekawde
     Thanks, Santos
     On Mon, Sep 17, 2018 at 8:22 PM Santos Das
         Hi,
         Could you kindly let me know how can we implement the flow
         control ? Protection against the badly behaving clients.
         HTTP/1.1 servers SHOULD maintain persistent connections
and use TCP's flow control
Post by Kunal Ekawde
         mechanisms to resolve temporary overloads, rather than
terminating connections with
Post by Kunal Ekawde
         the expectation that clients will retry. The latter
technique can exacerbate network
Post by Kunal Ekawde
         congestion.
          
         https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
         Thanks, Santos
--
~Kunal
Santos Das
2018-09-18 12:35:30 UTC
Permalink
Thanks Christian.

I have a question on "MHD_OPTION_CONNECTION_MEMORY_LIMIT" . I went through
the manual. How does this affect the send/recv buffer size per client
connection. What does it eventually translate to?

MHD_OPTION_CONNECTION_MEMORY_LIMIT - Maximum memory size per connection
(followed by a size_t). The default is 32 kB (32*1024 bytes) as defined by
the internal constant MHD_
POOL_SIZE_DEFAULT. Values above 128k are unlikely to result in much
benefit, as half of the memory will be typically used for IO, and TCP
buffers are unlikely to support window sizes above 64k on most systems.
Post by Christian Grothoff
Post by Santos Das
Hi Christian,
Thanks a lot. I have few questions in this regard -
a. When we put the connection in suspend state, can we pass a timeout
at the expiry of which the connection will be automatically resumed?
No.
Post by Santos Das
b. For asynchronous communication , i.e the application received the
request but is not able to send the response now (it needs to do some
work may be creating another request to another endpoint) , is it
mandatory to use suspend-resume only or there is some other mechanism
that we can use ?
If you use 'thread per connection', you could also simply block.
Post by Santos Das
c. How does the keep alive works in the HTTP server library ?
MHD takes care of it, it adds keep-alive headers and processes them
_unless_ explicitly overridden by the application.
Post by Santos Das
Could you please explain how the TCP's flow control mechanism is
helping in this case. A few lines would be great, please.
TCP flow control requires the kernel to provide message buffers for
retransmission (sender) and reordering (receiver). So those buffers can
and will be used by the kernel (on any OS) if the client sends
additional requests that the server is not yet processing.
Post by Santos Das
Sorry, lot of questions. But, please see if you could help in this.
If you suspend a connection, you are responsible to schedule some
job to
Post by Santos Das
resume it, after which MHD's timeout counter will start again (and of
course your response logic could then also just force MHD to close
the
Post by Santos Das
connection once MHD asks for response data). MHD timeouts are there
to
Post by Santos Das
detect (idle) clients that just keep connections open, not to prevent
the server from suspending a connection.
If the client closes a connection, it'll be detected if/when we try
to
Post by Santos Das
send data to the client and handled appropriately.
Happy hacking!
Christian
Post by Kunal Ekawde
a. client closes the connection before response is sent.
b. server app doesn't respond at all post suspend.
both cases there is no notification by MHD even if connection
timeout is
Post by Kunal Ekawde
specified and notify callback. How can these cases be handled ?
Thanks,
Kunal
Hi,
Just to add more, my application is single threaded and I am
running
Post by Kunal Ekawde
MHD inside that. I don't create additional threads. I use
suspend
Post by Santos Das
Post by Kunal Ekawde
and resume as suggested earlier as I do async processing.
So, I am thinking how can we implement flow control in this
scenario..
Post by Kunal Ekawde
Thanks, Santos
On Mon, Sep 17, 2018 at 8:22 PM Santos Das
Hi,
Could you kindly let me know how can we implement the flow
control ? Protection against the badly behaving clients.
HTTP/1.1 servers SHOULD maintain persistent connections
and use TCP's flow control
Post by Kunal Ekawde
mechanisms to resolve temporary overloads, rather than
terminating connections with
Post by Kunal Ekawde
the expectation that clients will retry. The latter
technique can exacerbate network
Post by Kunal Ekawde
congestion.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Thanks, Santos
--
~Kunal
Santos Das
2018-09-18 12:43:44 UTC
Permalink
Thanks Christian. Looks like you answered this question for Kunal Ekwade
already. Thank you.

But, still not clear from your reply, is it equal to the receive buffer
size ?
Post by Santos Das
Thanks Christian.
I have a question on "MHD_OPTION_CONNECTION_MEMORY_LIMIT" . I went through
the manual. How does this affect the send/recv buffer size per client
connection. What does it eventually translate to?
MHD_OPTION_CONNECTION_MEMORY_LIMIT - Maximum memory size per connection
(followed by a size_t). The default is 32 kB (32*1024 bytes) as defined by
the internal constant MHD_
POOL_SIZE_DEFAULT. Values above 128k are unlikely to result in much
benefit, as half of the memory will be typically used for IO, and TCP
buffers are unlikely to support window sizes above 64k on most systems.
Post by Christian Grothoff
Post by Santos Das
Hi Christian,
Thanks a lot. I have few questions in this regard -
a. When we put the connection in suspend state, can we pass a timeout
at the expiry of which the connection will be automatically resumed?
No.
Post by Santos Das
b. For asynchronous communication , i.e the application received the
request but is not able to send the response now (it needs to do some
work may be creating another request to another endpoint) , is it
mandatory to use suspend-resume only or there is some other mechanism
that we can use ?
If you use 'thread per connection', you could also simply block.
Post by Santos Das
c. How does the keep alive works in the HTTP server library ?
MHD takes care of it, it adds keep-alive headers and processes them
_unless_ explicitly overridden by the application.
Post by Santos Das
Could you please explain how the TCP's flow control mechanism is
helping in this case. A few lines would be great, please.
TCP flow control requires the kernel to provide message buffers for
retransmission (sender) and reordering (receiver). So those buffers can
and will be used by the kernel (on any OS) if the client sends
additional requests that the server is not yet processing.
Post by Santos Das
Sorry, lot of questions. But, please see if you could help in this.
If you suspend a connection, you are responsible to schedule some
job to
Post by Santos Das
resume it, after which MHD's timeout counter will start again (and
of
Post by Santos Das
course your response logic could then also just force MHD to close
the
Post by Santos Das
connection once MHD asks for response data). MHD timeouts are
there to
Post by Santos Das
detect (idle) clients that just keep connections open, not to
prevent
Post by Santos Das
the server from suspending a connection.
If the client closes a connection, it'll be detected if/when we try
to
Post by Santos Das
send data to the client and handled appropriately.
Happy hacking!
Christian
Post by Kunal Ekawde
a. client closes the connection before response is sent.
b. server app doesn't respond at all post suspend.
both cases there is no notification by MHD even if connection
timeout is
Post by Kunal Ekawde
specified and notify callback. How can these cases be handled ?
Thanks,
Kunal
Hi,
Just to add more, my application is single threaded and I am
running
Post by Kunal Ekawde
MHD inside that. I don't create additional threads. I use
suspend
Post by Santos Das
Post by Kunal Ekawde
and resume as suggested earlier as I do async processing.
So, I am thinking how can we implement flow control in this
scenario..
Post by Kunal Ekawde
Thanks, Santos
On Mon, Sep 17, 2018 at 8:22 PM Santos Das
Hi,
Could you kindly let me know how can we implement the flow
control ? Protection against the badly behaving clients.
HTTP/1.1 servers SHOULD maintain persistent connections
and use TCP's flow control
Post by Kunal Ekawde
mechanisms to resolve temporary overloads, rather than
terminating connections with
Post by Kunal Ekawde
the expectation that clients will retry. The latter
technique can exacerbate network
Post by Kunal Ekawde
congestion.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Thanks, Santos
--
~Kunal
Christian Grothoff
2018-09-18 13:00:32 UTC
Permalink
Post by Santos Das
Thanks Christian. Looks like you answered this question for Kunal Ekwade
already. Thank you. 
But, still not clear from your reply, is it equal to the receive buffer
size ?
MHD uses "whatever is left" (minus some reserves depending on what phase
processing is in) -- first for the receive buffer, and later for the
send buffer (re-using space from the receive buffer). In both cases it
is minus headers (headers sent and headers received!) and management
data structures.

The objective is simple: we must not use more than the memory limit per
connection, and within that constraint we make the buffers as big as we
(safely) can.

Christian Grothoff
2018-09-18 12:43:37 UTC
Permalink
Post by Santos Das
Thanks Christian.
I have a question on "MHD_OPTION_CONNECTION_MEMORY_LIMIT" . I went
through the manual. How does this affect the send/recv buffer size per
client connection. What does it eventually translate to?
It does not directly translate. Basically, the send/recv buffer for the
application payload is whatever is left after MHD allocated storage for
the HTTP header. So if you have a 32k buffer and a 1k header, you may
have 30+ kb for send/recv of payload, but if you have a 32k buffer and
an 8k HTTP header, you might have only 24k for the send/recv buffer.
Christian Grothoff
2018-09-18 09:48:01 UTC
Permalink
Hi!

Good news: You don't need to do anything. MHD will maintain persistent
TCP connections and use TCP's flow control mechanisms automatically.
You can _force_ MHD to not keep connections open by adding "Connection:
Close" to your HTTP response header manually, but by default MHD will do
the right thing.

This is independent of your threading model or the use of suspend/resume.

Happy hacking!

Christian
Post by Santos Das
Hi,
Just to add more, my application is single threaded and I am running MHD
inside that. I don't create additional threads. I use suspend and resume
as suggested earlier as I do async processing.
So, I am thinking how can we implement flow control in this scenario..
Thanks, Santos
Hi,
Could you kindly let me know how can we implement the flow control ?
Protection against the badly behaving clients.
HTTP/1.1 servers SHOULD maintain persistent connections and use TCP's flow control
mechanisms to resolve temporary overloads, rather than terminating connections with
the expectation that clients will retry. The latter technique can exacerbate network
congestion.
 
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Thanks, Santos
Santos Das
2018-09-18 11:34:55 UTC
Permalink
Hi Christian,

Thank you. Could you please explain how the TCP's flow control mechanism is
helping in this case. A few lines would be great, please.

thanks, santos
Post by Christian Grothoff
Hi!
Good news: You don't need to do anything. MHD will maintain persistent
TCP connections and use TCP's flow control mechanisms automatically.
Close" to your HTTP response header manually, but by default MHD will do
the right thing.
This is independent of your threading model or the use of suspend/resume.
Happy hacking!
Christian
Post by Santos Das
Hi,
Just to add more, my application is single threaded and I am running MHD
inside that. I don't create additional threads. I use suspend and resume
as suggested earlier as I do async processing.
So, I am thinking how can we implement flow control in this scenario..
Thanks, Santos
Hi,
Could you kindly let me know how can we implement the flow control ?
Protection against the badly behaving clients.
HTTP/1.1 servers SHOULD maintain persistent connections and use
TCP's flow control
Post by Santos Das
mechanisms to resolve temporary overloads, rather than terminating
connections with
Post by Santos Das
the expectation that clients will retry. The latter technique can
exacerbate network
Post by Santos Das
congestion.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
Thanks, Santos
Loading...