fr_bio_t *fr_bio_haproxy_alloc(TALLOC_CTX *ctx, fr_bio_cb_funcs_t *cb, fr_bio_t *next)
{
fr_bio_haproxy_t *my;
- uint8_t *data;
my = talloc_zero(ctx, fr_bio_haproxy_t);
if (!my) return NULL;
- data = talloc_array(my, uint8_t, HAPROXY_HEADER_V1_SIZE);
- if (!data) {
+ if (fr_bio_buf_alloc(my, &my->buffer, HAPROXY_HEADER_V1_SIZE) < 0) {
talloc_free(my);
return NULL;
}
- fr_bio_buf_init(&my->buffer, data, HAPROXY_HEADER_V1_SIZE);
-
my->bio.read = fr_bio_haproxy_read;
my->bio.write = fr_bio_null_write; /* can't write to this bio */
my->cb = *cb;
*/
static bool fr_bio_mem_buf_alloc(fr_bio_mem_t *my, fr_bio_buf_t *buf, size_t size)
{
- uint8_t *data;
-
if (size < 1024) size = 1024;
if (size > (1 << 20)) size = 1 << 20;
- data = talloc_array(my, uint8_t, size);
- if (!data) {
+ if (fr_bio_buf_alloc(my, buf, size) < 0) {
talloc_free(my);
return false;
}
- fr_bio_buf_init(buf, data, size);
return true;
}
rcode = next->write(next, NULL, my->cancelled.read, used);
if (rcode <= 0) return rcode;
- if ((size_t) rcode == used) {
+ my->cancelled.read += rcode;
+
+ if (fr_bio_buf_used(&my->cancelled) == 0) {
my->blocked = false;
my->bio.write = fr_bio_retry_write;
}
/*
- * We didn't write any of the partial packet, so we can't write out this one, either.
+ * We didn't write any of the saved partial packet, so we can't write out the current one,
+ * either.
*/
- my->cancelled.read += rcode;
return 0;
}
if (item->cancelled) return 0;
/*
- * If we've written a partial packet, then we cannot cancel this item.
- *
- * @todo - cache the rest of the packet data and send it, even if the item has been cancelled!
+ * If we've written a partial packet, jump through a bunch of hoops to cache the partial packet
+ * data. This lets the application cancel any pending packet, while still making sure that we
+ * don't break packet boundaries.
*/
if (my->partial == item) {
if (item->partial > 0) {
- uint8_t *ptr;
size_t size;
size = item->size - item->partial;
if (!my->cancelled.start) {
- ptr = talloc_array(my, uint8_t, size);
- if (!ptr) return -1;
-
- fr_bio_buf_init(&my->cancelled, ptr, size);
-
- } else if (size > (size_t) (my->cancelled.end - my->cancelled.start)) {
- ptr = talloc_array(my, uint8_t, size);
- if (!ptr) return -1;
+ if (fr_bio_buf_alloc(my, &my->cancelled, size)) return -1;
- talloc_free(my->cancelled.start);
- fr_bio_buf_init(&my->cancelled, ptr, size);
+ } else if (size > fr_bio_buf_size(&my->cancelled)) {
+ if (fr_bio_buf_alloc(my, &my->cancelled, size)) return -1;
}
fr_assert(fr_bio_buf_used(&my->cancelled) == 0);