check for an error case

if the coap pdu struct is larger than the headers that are stripped off
a datagram by the time it arrives at coap, all the nice zero-copying
stops working. instead of working around by allocating bigger headers
(which would go untested), it was decided to lock up. given how
reproducible the header calculations are, this will let the developer
know what's up early, if this ever happens to be critical at all.

there are two plausible causes for this to happen:

* the pdu struct grows, eg. because of additional fields or becaus it is
  used on architecture with large alignment requirements
* packages "come in shallow", that is, are created from an interface
  that barely has headers. such an interface could be a network
  interfaces created from a hardware network stack.

this also changes the sizes of allocated pdus, in which previously, the
probelm was not considered and covered by overallocation.
This commit is contained in:
chrysn committed 2013-11-17 16:53:35 +01:00
1 parent 1b1f4d0db4
commit c983c853d7
1 file changed
+10 -4
+10 -4
View File
@@ -62,7 +62,8 @@ coap_pdu_from_pbuf(struct pbuf *pbuf)
void *data = pbuf->payload;
coap_pdu_t *result;
pbuf_header(pbuf, sizeof(coap_pdu_t));
u8_t header_error = pbuf_header(pbuf, sizeof(coap_pdu_t));
LWIP_ASSERT("CoAP PDU header does not fit in existing header space", header_error == 0);
result = (coap_pdu_t *)pbuf->payload;
@@ -98,11 +99,16 @@ coap_pdu_init(unsigned char type, unsigned char code,
pdu = (coap_pdu_t *)memb_alloc(&pdu_storage);
#endif
#ifdef WITH_LWIP
p = pbuf_alloc(PBUF_TRANSPORT, sizeof(coap_pdu_t) + size, PBUF_RAM);
if (p != NULL)
p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
if (p != NULL) {
u8_t header_error = pbuf_header(p, sizeof(coap_pdu_t));
/* we could catch that case and allocate larger memory in advance, but then
* again, we'd run into greater trouble with incoming packages anyway */
LWIP_ASSERT("CoAP PDU header does not fit in transport header", header_error == 0);
pdu = p->payload;
else
} else {
pdu = NULL;
}
#endif
if (pdu) {
coap_pdu_clear(pdu, size);