From 0d5f2e12594e811134053b4ada5394789c1d7dd8 Mon Sep 17 00:00:00 2001 From: Eric Long Date: Thu, 25 Jul 2024 11:14:02 +0800 Subject: [PATCH] `struct pktbuf` -> `struct packet_buf`, also switch to use `struct queue` internally --- src/mimic.h | 24 ++++++++++++------------ src/queue.c | 44 +++++++++++++++++--------------------------- src/run.c | 20 ++++++++++---------- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/src/mimic.h b/src/mimic.h index 42ea8c9..05f5b3e 100644 --- a/src/mimic.h +++ b/src/mimic.h @@ -73,22 +73,22 @@ struct queue_node* queue_pop(struct queue* q); void queue_node_free(struct queue_node* node); void queue_free(struct queue* q); -// TODO: use `struct queue` // TODO: limit stored packet count/size -struct pktbuf { +struct packet_buf { struct conn_tuple conn; - struct packet { - struct packet* next; - char* data; - size_t len; - } *head, *tail; + struct queue queue; +}; + +struct packet { + char* data; + size_t len; }; -struct pktbuf* pktbuf_new(struct conn_tuple* conn); -int pktbuf_push(struct pktbuf* buf, const char* data, size_t len, bool l4_csum_partial); -int pktbuf_consume(struct pktbuf* buf, bool* consumed); -void pktbuf_drain(struct pktbuf* buf); -void pktbuf_free(struct pktbuf* buf); +struct packet_buf* packet_buf_new(struct conn_tuple* conn); +int packet_buf_push(struct packet_buf* buf, const char* data, size_t len, bool l4_csum_partial); +int packet_buf_consume(struct packet_buf* buf, bool* consumed); +void packet_buf_drain(struct packet_buf* buf); +void packet_buf_free(struct packet_buf* buf); int notify_ready(); diff --git a/src/queue.c b/src/queue.c index cddd64b..8f874d1 100644 --- a/src/queue.c +++ b/src/queue.c @@ -54,7 +54,6 @@ void queue_free(struct queue* q) { static inline struct packet* packet_new(const char* data, size_t len, bool l4_csum_partial) { struct packet* result = malloc(sizeof(*result)); if (!result) return NULL; - result->next = NULL; result->data = malloc(len); result->len = len; memcpy(result->data, data, len); @@ -70,30 +69,26 @@ static inline void packet_free(struct packet* p) { free(p); } -struct pktbuf* pktbuf_new(struct conn_tuple* conn) { - struct pktbuf* result = malloc(sizeof(*result)); +static inline void _packet_free_void(void* p) { packet_free(p); } + +struct packet_buf* packet_buf_new(struct conn_tuple* conn) { + struct packet_buf* result = calloc(1, sizeof(*result)); if (!result) return NULL; result->conn = *conn; - result->head = result->tail = NULL; return result; } -int pktbuf_push(struct pktbuf* buf, const char* data, size_t len, bool l4_csum_partial) { +int packet_buf_push(struct packet_buf* buf, const char* data, size_t len, bool l4_csum_partial) { struct packet* pkt = try_p(packet_new(data, len, l4_csum_partial)); - if (buf->head) { - buf->tail->next = pkt; - buf->tail = pkt; - } else { - buf->head = buf->tail = pkt; - } + queue_push(&buf->queue, pkt, _packet_free_void); return 0; } -int pktbuf_consume(struct pktbuf* buf, bool* consumed) { +int packet_buf_consume(struct packet_buf* buf, bool* consumed) { if (!buf) { *consumed = true; return 0; - } else if (!buf->head) { + } else if (!buf->queue.head) { *consumed = true; free(buf); return 0; @@ -111,31 +106,26 @@ int pktbuf_consume(struct pktbuf* buf, bool* consumed) { try_e(bind(sk, (struct sockaddr*)&saddr, sizeof(saddr))); int ret = 0; - for (struct packet *p = buf->head, *oldp; p;) { + struct queue_node* pn; + while ((pn = queue_pop(&buf->queue))) { + struct packet* p = pn->data; ret = ret ?: sendto(sk, p->data, p->len, 0, (struct sockaddr*)&daddr, sizeof(daddr)); if (ret > 0) ret = 0; - oldp = p; - p = p->next; - packet_free(oldp); + queue_node_free(pn); } *consumed = true; free(buf); - return ret; + return ret < 0 ? -errno : 0; } -void pktbuf_drain(struct pktbuf* buf) { +void packet_buf_drain(struct packet_buf* buf) { if (!buf) return; - for (struct packet *p = buf->head, *oldp; p;) { - oldp = p; - p = p->next; - packet_free(oldp); - } - buf->head = buf->tail = NULL; + queue_free(&buf->queue); } -void pktbuf_free(struct pktbuf* buf) { +void packet_buf_free(struct packet_buf* buf) { if (!buf) return; - pktbuf_drain(buf); + packet_buf_drain(buf); free(buf); } diff --git a/src/run.c b/src/run.c index b1836a7..b4c3ec3 100644 --- a/src/run.c +++ b/src/run.c @@ -25,10 +25,10 @@ #include #include +#include "bpf_skel.h" #include "common/checksum.h" #include "common/defs.h" #include "common/try.h" -#include "bpf_skel.h" #include "log.h" #include "mimic.h" @@ -216,8 +216,8 @@ static int store_packet(struct bpf_map* conns, struct conn_tuple* conn_key, cons log_warn(_("store packet event processed after connection was established")); return 0; } - if (!conn.pktbuf) conn.pktbuf = (uintptr_t)try2_p(pktbuf_new(conn_key)); - try2_e(pktbuf_push((struct pktbuf*)conn.pktbuf, data, len, l4_csum_partial)); + if (!conn.pktbuf) conn.pktbuf = (uintptr_t)try2_p(packet_buf_new(conn_key)); + try2_e(packet_buf_push((struct packet_buf*)conn.pktbuf, data, len, l4_csum_partial)); try2(bpf_map__update_elem(conns, conn_key, sizeof(*conn_key), &conn, sizeof(conn), BPF_EXIST | BPF_F_LOCK)); return 0; @@ -227,7 +227,7 @@ static int store_packet(struct bpf_map* conns, struct conn_tuple* conn_key, cons _("connection released when attempting to store packet; freeing packet buffer")); retcode = 0; } - if (conn.pktbuf) pktbuf_free((struct pktbuf*)conn.pktbuf); + if (conn.pktbuf) packet_buf_free((struct packet_buf*)conn.pktbuf); return retcode; } @@ -257,8 +257,8 @@ static int _handle_rb_event(struct bpf_map* conns, const char* ifname, void* ctx break; case RB_ITEM_CONSUME_PKTBUF: name = N_("consuming packet buffer"); - ret = pktbuf_consume((struct pktbuf*)item->pktbuf, &consumed); - if (!consumed) pktbuf_free((struct pktbuf*)item->pktbuf); + ret = packet_buf_consume((struct packet_buf*)item->pktbuf, &consumed); + if (!consumed) packet_buf_free((struct packet_buf*)item->pktbuf); if (ret < 0) { log_debug(_("error %s: %s"), gettext(name), strerror(-ret)); ret = 0; @@ -266,7 +266,7 @@ static int _handle_rb_event(struct bpf_map* conns, const char* ifname, void* ctx break; case RB_ITEM_FREE_PKTBUF: name = N_("freeing packet buffer"); - pktbuf_free((struct pktbuf*)item->pktbuf); + packet_buf_free((struct packet_buf*)item->pktbuf); break; default: name = N_("handling unknown ring buffer item"); @@ -319,7 +319,7 @@ static inline int time_diff_sec(__u64 a, __u64 b) { static int do_routine(int conns_fd, const char* ifname) { struct _conn_to_free { struct conn_tuple key; - struct pktbuf* buf; + struct packet_buf* buf; }; int retcode = 0; @@ -384,7 +384,7 @@ static int do_routine(int conns_fd, const char* ifname) { log_destroy(LOG_WARN, &key, DESTROY_TIMED_OUT); struct _conn_to_free* item = malloc(sizeof(*item)); item->key = key; - item->buf = (struct pktbuf*)conn.pktbuf; + item->buf = (struct packet_buf*)conn.pktbuf; queue_push(&free_queue, item, free); send_ctrl_packet(&key, RST, conn.seq, 0, 0, ifname); } @@ -396,7 +396,7 @@ cleanup:; while ((node = queue_pop(&free_queue))) { struct _conn_to_free* item = node->data; bpf_map_delete_elem(conns_fd, &item->key); - pktbuf_free(item->buf); + packet_buf_free(item->buf); queue_node_free(node); } return retcode;