New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC7959: Move block handling logic down into libcoap #554
Conversation
|
Can you please rebase? |
|
rebase code pushed |
405382e
to
b9220b4
Compare
|
Code tidy up, minor fixes following testing just pushed. |
|
rebased and code pushed |
|
rebase and fix example error and pushed code |
|
Fix bad rebase merge from #484 and code pushed |
|
Rebased and updated after extensive testing. |
5a738c2
to
67f72a2
Compare
Thanks again for this really awesome contribution. Here are some comments from a first review iteration.
src/block.c
Outdated
|
|
||
| /* Check if resource+query is already in use for large bodies (unlikely) */ | ||
| lg_xmit = session->lg_xmit; | ||
| while (lg_xmit) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to always use the utlist macros to improve readability and to avoid errors due to own linked-list implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK - will work on using LL_
|
Separate commits pushed - will get squashed at some point. The LL_ updates (last comment) still outstanding. |
|
Previous 2 commits now squashed, new commit for latest changes. Working on LL_. |
|
Uh, sorry, I just merged PR #583 and did not notice that this will result in a conflict with this PR. |
175c70e
to
937b7fc
Compare
|
My mistake, I was expecting Size2 which is not there. Working on a fix. |
|
Fixed Size2 missing issue and code pushed. |
|
..and fix another missing Size2 issue. Code pushed. |
|
Thanks, this works better now. But it still seems to block when setting a block number larger than 0 with |
|
I guess that if the client explicitly asks for a I will fix it so that explicit |
|
That makes sense to me. |
|
Code (and docs) now correctly support random access block requests. Previous version of coap-client also hung on a single random access block request. |
|
Updated code pushed. |
This change removes the need for applications having to know about handling requests for the next block etc. It also gives the application the ability to pass a large body of data to be transmitted and be told when this body is no longer required. This logic is enabled in libcoap by setting COAP_BLOCK_USE_LIBCOAP using coap_context_set_block_mode() This change breaks down into 4 specific areas 1) Client doing a PUT/POST etc. of a large amount of data (BLOCK1). coap_add_data_large_request() is used which provides a 'finished with data' callback function as well as adding required options to the PDUs. This function calls coap_add_data_large_internal(). Internal coap_handle_response_send_block() sends off the subsequent blocks (using session->lg_xmit). 2) Server receiving PUT/POST etc. of a large amount of data (BLOCK1). Internal coap_handle_request_get_block() acknowledges the appropriate blocks (using session->lg_srcv) and either passes in the individual blocks or the body depending on whether COAP_BLOCK_SINGLE_BODY is set or not using coap_context_set_block_mode(). 3) Server sending a large data response to GET / observe (BLOCK2) coap_add_data_large_response() is used which provides a 'finished with data' callback function. This function calls coap_add_data_large_internal() as well as filling in the necessary options for each PDU. Interal coap_handle_request_send_block() will then send the next requested block (using session->lg_xmit). 4) Client receiving a large data response (BLOCK2) coap_send_large() for the initial request sets this up. Internal coap_handle_response_get_block() will then request the next block when previous block received (using session->lg_crcv) and either passes the individual blocks or the body depending on COAP_BLOCK_SINGLE_BODY being set in coap_context_set_block_mode(). ---- The following new internal functions have been added coap_handle_request_get_block() coap_handle_request_send_block() coap_handle_response_get_block() coap_handle_response_send_block() coap_add_data_large_internal() The following new functions have been added. coap_add_data_large_request() coap_add_data_large_response() coap_context_set_block_mode() coap_get_data_large() coap_pdu_duplicate() coap_send_large() coap_session_init_token() coap_session_new_token() The coap_session_init_token() and coap_session_new_token() were added to make the handling of unique tokens for each request/response easier. https://datatracker.ietf.org/doc/html/draft-ietf-core-echo-request-tag-10#section-4 New files include/coap2/coap_block_internal.h: man/coap_block.txt.in: New memory types COAP_LG_XMIT COAP_LG_SRCV COAP_LG_CRCV
Remove block handling logic from coap-client and coap-server and make use of the new libcoap functionality. Add in new -L option to be able to define how libcoap is to work with block handling. Update documentation accordingly.
|
rebased and pushed following #571 merge. |
|
Thanks! Merging... |
Merging obgm#522 and obgm#554 into develop caused Observe CON 2.05 initial block response not to get an ACK from the client and so the Observe response kept getting re-transmitted and caused other CON traffic to get queued up. Troubleshooting highlighted an issue when a PUT/POST was updating the contents of a resource and an Observe was active sending many payloads in a body. src/net.c: Make sure that an ACK is sent (if appropriate) when working with a block based response. examples/coap-server.c: Give dynamic data associated with a resource a reference count, and only free off the data when the reference count has dropped to 0.
Merging obgm#552 and obgm#554 into develop caused Observe CON 2.05 initial block response not to get an ACK from the client and so the Observe response kept getting re-transmitted and caused other CON traffic to get queued up. Troubleshooting highlighted an issue when a PUT/POST was updating the contents of a resource and an Observe was active sending many payloads in a body. src/net.c: Make sure that an ACK is sent (if appropriate) when working with a block based response. examples/coap-server.c: Give dynamic data associated with a resource a reference count, and only free off the data when the reference count has dropped to 0.
Merging obgm#552 and obgm#554 into develop caused Observe CON 2.05 initial block response not to get an ACK from the client and so the Observe response kept getting re-transmitted and caused other CON traffic to get queued up. Troubleshooting highlighted an issue when a PUT/POST was updating the contents of a resource and an Observe was active sending many payloads in a body. src/net.c: Make sure that an ACK is sent (if appropriate) when working with a block based response. examples/coap-server.c: Give dynamic data associated with a resource a reference count, and only free off the data when the reference count has dropped to 0.
An empty response ACK is ignored if there was a request on the Send-Q. However if there was a subsequent duplicate ACK this would then fall through to the general handling logic in coap_dispatch(), and would trigger the ping handler (if set) and send a RST (if not mcast) which is not correct. Correct a change added in by obgm#554 so that all empty response ACKs are ignored.
An empty response ACK is ignored if there was a request on the Send-Q. However if there was a subsequent duplicate ACK this would then fall through to the general handling logic in coap_dispatch(), and would trigger the ping handler (if set) and send a RST (if not mcast) which is not correct. Correct a change added in by obgm#554 so that all empty response ACKs are ignored.
This PR is broken down into 2 parts - libcoap changes and example changes.
libcoap changes
RFC7959: Move block handling logic down into libcoap
This change removes the need for applications having to know about handling
requests for the next block etc. It also gives the application the ability
to pass a large body of data to be transmitted and be told when this body is
no longer required.
This logic is enabled in libcoap by setting COAP_BLOCK_USE_LIBCOAP using
coap_context_set_block_mode()
This change breaks down into 4 specific areas
coap_add_data_large_request() is used which provides a 'finished with data'
callback function as well as adding required options to the PDUs. This
function calls coap_add_data_large_internal().
Internal coap_handle_response_send_block() sends off the subsequent blocks
(using session->lg_xmit).
Internal coap_handle_request_get_block() acknowledges the appropriate blocks
(using session->lg_srcv) and either passes in the individual blocks or the body
depending on whether COAP_BLOCK_SINGLE_BODY is set or not using
coap_context_set_block_mode().
coap_add_data_large_response() is used which provides a 'finished with data'
callback function. This function calls coap_add_data_large_internal() as well
as filling in the necessary options for each PDU.
Interal coap_handle_request_send_block() will then send the next requested block
(using session->lg_xmit).
coap_send_large() for the initial request sets this up.
Internal coap_handle_response_get_block() will then request the next block when
previous block received (using session->lg_crcv) and either passes the
individual blocks or the body depending on COAP_BLOCK_SINGLE_BODY being set in
coap_context_set_block_mode().
The following new internal functions have been added
coap_handle_request_get_block()
coap_handle_request_send_block()
coap_handle_response_get_block()
coap_handle_response_send_block()
coap_add_data_large_internal()
The following new functions have been added.
coap_add_data_large_request()
coap_add_data_large_response()
coap_context_set_block_mode()
coap_get_data_large()
coap_pdu_duplicate()
coap_send_large()
coap_session_init_token()
coap_session_new_token()
The coap_session_init_token() and coap_session_new_token() were added to make
the handling of unique tokens for each request/response easier.
https://datatracker.ietf.org/doc/html/draft-ietf-core-echo-request-tag-10#section-4
New files
include/coap2/coap_block_internal.h:
man/coap_block.txt.in:
New memory types
COAP_LG_XMIT
COAP_LG_SRCV
COAP_LG_CRCV
Example changes
RFC7959: Add in example support using updated libcoap handling of blocks
Remove block handling logic from coap-client and coap-server and make use of the
new libcoap functionality.
Add in new -L option to be able to define how libcoap is to work with block
handling. Update documentation accordingly.