-
Notifications
You must be signed in to change notification settings - Fork 103
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
Fix ulimited body parsing #1983
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -370,7 +370,8 @@ typedef struct { | |
* @conn - connection which the message was received on; | ||
* @destructor - called when a connection is destroyed; | ||
* @crlf - pointer to CRLF between headers and body; | ||
* @body - pointer to the body of a message; | ||
* @body - contains start of the body of a message and length of | ||
* whole body. Do not use as regular TfwStr; | ||
* | ||
* TfwStr members must be the last for efficient scanning. | ||
* | ||
|
@@ -411,8 +412,6 @@ struct tfw_http_msg_t { | |
TFW_HTTP_MSG_COMMON; | ||
}; | ||
|
||
#define __MSG_STR_START(m) (&(m)->crlf) | ||
|
||
#define TFW_HTTP_COND_IF_MSINCE 0x0001 | ||
#define TFW_HTTP_COND_ETAG_ANY 0x0002 | ||
#define TFW_HTTP_COND_ETAG_LIST 0x0004 | ||
|
@@ -495,9 +494,6 @@ struct tfw_http_req_t { | |
unsigned char method_override; | ||
}; | ||
|
||
#define TFW_HTTP_REQ_STR_START(r) __MSG_STR_START(r) | ||
#define TFW_HTTP_REQ_STR_END(r) ((&(r)->uri_path) + 1) | ||
|
||
#define TFW_IDX_BITS 12 | ||
#define TFW_D_IDX_BITS 4 | ||
|
||
|
@@ -600,9 +596,6 @@ typedef struct { | |
#define TFW_HDR_MAP_SZ(cnt) (sizeof(TfwHttpHdrMap) \ | ||
+ sizeof(TfwHdrIndex) * (cnt)) | ||
|
||
#define TFW_HTTP_RESP_STR_START(r) __MSG_STR_START(r) | ||
#define TFW_HTTP_RESP_STR_END(r) ((&(r)->body) + 1) | ||
|
||
#define TFW_HTTP_RESP_CUT_BODY_SZ(r) \ | ||
(r)->stream ? \ | ||
(r)->body.len - (r)->cut.len : \ | ||
|
@@ -713,6 +706,78 @@ tfw_http_msg_header_table_size(void) | |
return TFW_HTTP_HDR_RAW - TFW_HTTP_HDR_REGULAR - 1; | ||
} | ||
|
||
/** | ||
* Initialize body iterator. Should be used as helper for iterating over | ||
* HTTP message body. | ||
* | ||
* @it - Generic message iterator that be used as body iterator. | ||
* @chunk - Current body chunk to init. | ||
* @body_start - Position in sk_buff @start to start itarating. | ||
* @start - sk_buff to start with. | ||
* @end - sk_buff where stop itarating. Usually skb_head of message. | ||
*/ | ||
static inline int | ||
tfw_body_iter_init(TfwMsgIter* it, TfwStr* chunk, char* body_start, | ||
struct sk_buff* start, struct sk_buff* end) | ||
{ | ||
int r; | ||
|
||
it->skb_head = end; | ||
it->skb = start; | ||
it->frag = -1; | ||
|
||
/* Set starting position. */ | ||
r = ss_skb_find_frag_by_offset(it->skb, body_start, &it->frag); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we expect to find start of the body in the first skb? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not first skb. |
||
if (unlikely(r)) | ||
return r; | ||
|
||
if (it->frag == -1) { | ||
unsigned int size = skb_headlen(it->skb); | ||
|
||
chunk->len = (char*)(it->skb->data + size) - body_start; | ||
} else { | ||
skb_frag_t *f = &skb_shinfo(it->skb)->frags[it->frag]; | ||
unsigned int size = skb_frag_size(f); | ||
|
||
chunk->len = (char*)(skb_frag_address(f) + size) - body_start; | ||
} | ||
|
||
chunk->data = body_start; | ||
|
||
return 0; | ||
} | ||
|
||
/** | ||
* Move to next body @chunk for iterator @it. | ||
*/ | ||
static inline void | ||
tfw_body_iter_next(TfwMsgIter* it, TfwStr* chunk) | ||
{ | ||
if (++it->frag >= skb_shinfo(it->skb)->nr_frags) { | ||
it->skb = it->skb->next; | ||
if (it->skb == it->skb_head) { | ||
chunk->data = NULL; | ||
chunk->len = 0; | ||
return; | ||
} | ||
|
||
it->frag = -(!!skb_headlen(it->skb)); | ||
} | ||
|
||
if (it->frag == -1) { | ||
chunk->data = it->skb->data; | ||
chunk->len = skb_headlen(it->skb); | ||
} else { | ||
skb_frag_t *f = &skb_shinfo(it->skb)->frags[it->frag]; | ||
|
||
chunk->data = skb_frag_address(f); | ||
chunk->len = skb_frag_size(f); | ||
} | ||
} | ||
|
||
#define TFW_BODY_ITER_WALK(it, c) \ | ||
for (; (c)->data; tfw_body_iter_next((it), (c))) | ||
|
||
typedef void (*tfw_http_cache_cb_t)(TfwHttpMsg *); | ||
|
||
/* External HTTP functions. */ | ||
|
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.
tfw_str_crc32_calc is now unused, we can remove it from our code and tests
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 would prefer don't remove this function. Time to time we use crc32 for
TfwStr
even for debug purposes and it useful to have such function.