diff --git a/prefab/conn_blocks/tcp_connblock.c b/prefab/conn_blocks/tcp_connblock.c index bf6158f..db301cd 100644 --- a/prefab/conn_blocks/tcp_connblock.c +++ b/prefab/conn_blocks/tcp_connblock.c @@ -275,6 +275,11 @@ int tcp_receive_segment_cb(const Pckt *pckt, PcktSieveLayerTag tag) { // maintain retry counter tcps->retries = willRetry ? (tcps->retries + 1) : 0; + // release options if not NULL + if (tcpProps->options != NULL) { + tcpopt_chain_free(tcpProps->options); + } + // release descriptor if not meaningful anymore if (ret == SIEVE_LAYER_REMOVE_THIS) { cbdt_release(E.cbdt, tcps->d); // release descriptor diff --git a/prefab/packet_parsers/tcp_segment.c b/prefab/packet_parsers/tcp_segment.c index 28da392..1ac0bfb 100644 --- a/prefab/packet_parsers/tcp_segment.c +++ b/prefab/packet_parsers/tcp_segment.c @@ -205,4 +205,13 @@ TcpOption *tcpopt_new(uint32_t kind, uint32_t size) { return opt; } +void tcpopt_chain_free(const TcpOption * opt) { + const TcpOption * iter = opt, *next; + while (iter) { + next = iter->next; + dynmem_free(iter); + iter = next; + } + +} diff --git a/prefab/packet_parsers/tcp_segment.h b/prefab/packet_parsers/tcp_segment.h index 28afa6b..d7420f7 100644 --- a/prefab/packet_parsers/tcp_segment.h +++ b/prefab/packet_parsers/tcp_segment.h @@ -36,6 +36,12 @@ typedef struct TcpOption_ { */ TcpOption * tcpopt_new(uint32_t kind, uint32_t size); +/** + * Release a chain of TCP options + * @param opt pointer to the chain's first element to release + */ +void tcpopt_chain_free(const TcpOption * opt); + /** * TCP segment properties. */