1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Track the total size of every PacketQueue.

The queue-node structure shared between PktIn and PktOut now has a
'formal_size' field, which is initialised appropriately by the various
packet constructors. And the PacketQueue structure has a 'total_size'
field which tracks the sum of the formal sizes of all the packets on
the queue, and is automatically updated by the push, pop and
concatenate functions.

No functional change, and nothing uses the new fields yet: this is
infrastructure that will be used in the next commit.

(cherry picked from commit 0ff13ae773)
This commit is contained in:
Simon Tatham 2020-02-05 19:32:22 +00:00
parent 35cc7b1cb6
commit 7c3778ad67
5 changed files with 36 additions and 4 deletions

2
ssh.h
View File

@ -52,6 +52,7 @@ struct ssh_channel;
typedef struct PacketQueueNode PacketQueueNode;
struct PacketQueueNode {
PacketQueueNode *next, *prev;
size_t formal_size; /* contribution to PacketQueueBase's total_size */
bool on_free_queue; /* is this packet scheduled for freeing? */
};
@ -84,6 +85,7 @@ typedef struct PktOut {
typedef struct PacketQueueBase {
PacketQueueNode end;
size_t total_size; /* sum of all formal_size fields on the queue */
struct IdempotentCallback *ic;
} PacketQueueBase;

View File

@ -236,6 +236,7 @@ static void ssh1_bpp_handle_input(BinaryPacketProtocol *bpp)
NULL, 0, NULL);
}
s->pktin->qnode.formal_size = get_avail(s->pktin);
pq_push(&s->bpp.in_pq, s->pktin);
{

View File

@ -129,6 +129,7 @@ static void ssh2_bare_bpp_handle_input(BinaryPacketProtocol *bpp)
continue;
}
s->pktin->qnode.formal_size = get_avail(s->pktin);
pq_push(&s->bpp.in_pq, s->pktin);
s->pktin = NULL;
}

View File

@ -589,6 +589,7 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
continue;
}
s->pktin->qnode.formal_size = get_avail(s->pktin);
pq_push(&s->bpp.in_pq, s->pktin);
{

View File

@ -35,6 +35,7 @@ void pq_base_push(PacketQueueBase *pqb, PacketQueueNode *node)
node->prev = pqb->end.prev;
node->next->prev = node;
node->prev->next = node;
pqb->total_size += node->formal_size;
if (pqb->ic)
queue_idempotent_callback(pqb->ic);
@ -47,6 +48,7 @@ void pq_base_push_front(PacketQueueBase *pqb, PacketQueueNode *node)
node->next = pqb->end.next;
node->next->prev = node;
node->prev->next = node;
pqb->total_size += node->formal_size;
if (pqb->ic)
queue_idempotent_callback(pqb->ic);
@ -72,6 +74,23 @@ static IdempotentCallback ic_pktin_free = {
pktin_free_queue_callback, NULL, false
};
static inline void pq_unlink_common(PacketQueueBase *pqb,
PacketQueueNode *node)
{
node->next->prev = node->prev;
node->prev->next = node->next;
/* Check total_size doesn't drift out of sync downwards, by
* ensuring it doesn't underflow when we do this subtraction */
assert(pqb->total_size >= node->formal_size);
pqb->total_size -= node->formal_size;
/* Check total_size doesn't drift out of sync upwards, by checking
* that it's returned to exactly zero whenever a queue is
* emptied */
assert(pqb->end.next != &pqb->end || pqb->total_size == 0);
}
static PktIn *pq_in_after(PacketQueueBase *pqb,
PacketQueueNode *prev, bool pop)
{
@ -80,14 +99,14 @@ static PktIn *pq_in_after(PacketQueueBase *pqb,
return NULL;
if (pop) {
node->next->prev = node->prev;
node->prev->next = node->next;
pq_unlink_common(pqb, node);
node->prev = pktin_freeq_head.prev;
node->next = &pktin_freeq_head;
node->next->prev = node;
node->prev->next = node;
node->on_free_queue = true;
queue_idempotent_callback(&ic_pktin_free);
}
@ -102,8 +121,8 @@ static PktOut *pq_out_after(PacketQueueBase *pqb,
return NULL;
if (pop) {
node->next->prev = node->prev;
node->prev->next = node->next;
pq_unlink_common(pqb, node);
node->prev = node->next = NULL;
}
@ -115,6 +134,7 @@ void pq_in_init(PktInQueue *pq)
pq->pqb.ic = NULL;
pq->pqb.end.next = pq->pqb.end.prev = &pq->pqb.end;
pq->after = pq_in_after;
pq->pqb.total_size = 0;
}
void pq_out_init(PktOutQueue *pq)
@ -122,6 +142,7 @@ void pq_out_init(PktOutQueue *pq)
pq->pqb.ic = NULL;
pq->pqb.end.next = pq->pqb.end.prev = &pq->pqb.end;
pq->after = pq_out_after;
pq->pqb.total_size = 0;
}
void pq_in_clear(PktInQueue *pq)
@ -153,6 +174,8 @@ void pq_base_concatenate(PacketQueueBase *qdest,
{
struct PacketQueueNode *head1, *tail1, *head2, *tail2;
size_t total_size = q1->total_size + q2->total_size;
/*
* Extract the contents from both input queues, and empty them.
*/
@ -164,6 +187,7 @@ void pq_base_concatenate(PacketQueueBase *qdest,
q1->end.next = q1->end.prev = &q1->end;
q2->end.next = q2->end.prev = &q2->end;
q1->total_size = q2->total_size = 0;
/*
* Link the two lists together, handling the case where one or
@ -206,6 +230,8 @@ void pq_base_concatenate(PacketQueueBase *qdest,
if (qdest->ic)
queue_idempotent_callback(qdest->ic);
}
qdest->total_size = total_size;
}
/* ----------------------------------------------------------------------
@ -235,6 +261,7 @@ static void ssh_pkt_adddata(PktOut *pkt, const void *data, int len)
sgrowarrayn_nm(pkt->data, pkt->maxlen, pkt->length, len);
memcpy(pkt->data + pkt->length, data, len);
pkt->length += len;
pkt->qnode.formal_size = pkt->length;
}
static void ssh_pkt_BinarySink_write(BinarySink *bs,