diff options
-rw-r--r-- | include/xhiv.h | 3 | ||||
-rw-r--r-- | src/server.c | 36 |
2 files changed, 27 insertions, 12 deletions
diff --git a/include/xhiv.h b/include/xhiv.h index 0063cf3..426918c 100644 --- a/include/xhiv.h +++ b/include/xhiv.h @@ -36,7 +36,10 @@ #define XHIV_NO_SET_SEQUENCE 0x01 /* Don't set sequence number in reply */ typedef struct xhiv_response { + /* next is used to make up the list of responses to search through. + Once one is found, all the responses along the chain are sent. */ struct xhiv_response *next; + struct xhiv_response *chain; uint16_t reqType; /* Request code, extension number or XHIV_REQ constant */ uint16_t reqMinor; /* Extension minor request code */ uint32_t sequence; /* Sequence number, or XHIV_SEQ_IGNORE */ diff --git a/src/server.c b/src/server.c index 38fa584..24a9872 100644 --- a/src/server.c +++ b/src/server.c @@ -227,29 +227,41 @@ static client_response_buffer * AddResponseToBuffer(client_response_buffer *crb, const xhiv_response *response, uint32_t sequence) { - client_response_buffer *new_crb; + client_response_buffer *new_crb_head = NULL, *new_crb_tail = NULL; + const xhiv_response *r; - uint64_t total_bytes= ((uint64_t) response->length) << 2; - assert(total_bytes >= response->response_datalen); + for (r = response; r != NULL; r = r->chain) { + client_response_buffer *new_crb; - new_crb = calloc(1, sizeof(client_response_buffer)); - assert(new_crb != NULL); + uint64_t total_bytes= ((uint64_t) r->length) << 2; + assert(total_bytes >= r->response_datalen); - new_crb->response_data = response->response_data; - new_crb->response_datalen = response->response_datalen; - new_crb->length = response->length; - new_crb->response_sequence = (response->flags & XHIV_NO_SET_SEQUENCE) - ? XHIV_SEQ_IGNORE : sequence; + new_crb = calloc(1, sizeof(client_response_buffer)); + assert(new_crb != NULL); + + new_crb->response_data = r->response_data; + new_crb->response_datalen = r->response_datalen; + new_crb->length = r->length; + new_crb->response_sequence = (r->flags & XHIV_NO_SET_SEQUENCE) + ? XHIV_SEQ_IGNORE : sequence; + + if (new_crb_tail != NULL) { + new_crb_tail->next = new_crb; + new_crb_tail = new_crb; + } else { + new_crb_head = new_crb_tail = new_crb; + } + } if (crb == NULL) - crb = new_crb; + crb = new_crb_head; else { client_response_buffer *n; for (n = crb ; n->next != NULL; n = n->next) { /* find end of list */ } - n->next = new_crb; + n->next = new_crb_head; } return crb; } |