Zero-copy TX: span_writer packer, static buffers, no vector returns
This commit is contained in:
@@ -139,6 +139,8 @@ static void handle_arp(const uint8_t* frame, size_t len) {
|
||||
send_raw(&reply, sizeof(reply));
|
||||
}
|
||||
|
||||
static uint8_t tx_buf[1514];
|
||||
|
||||
static void handle_udp(const uint8_t* frame, size_t len) {
|
||||
if (len < sizeof(udp_header)) return;
|
||||
auto& pkt = *reinterpret_cast<const udp_header*>(frame);
|
||||
@@ -154,41 +156,36 @@ static void handle_udp(const uint8_t* frame, size_t len) {
|
||||
auto* payload = frame + sizeof(udp_header);
|
||||
size_t payload_len = udp_len - 8;
|
||||
|
||||
auto responses = msg_handler(std::span<const uint8_t>{payload, payload_len});
|
||||
span_writer resp(tx_buf + sizeof(udp_header), sizeof(tx_buf) - sizeof(udp_header));
|
||||
size_t resp_len = msg_handler(std::span<const uint8_t>{payload, payload_len}, resp);
|
||||
if (resp_len == 0) return;
|
||||
|
||||
for (auto& resp : responses) {
|
||||
uint8_t reply_buf[1514];
|
||||
size_t udp_data_len = resp.size();
|
||||
size_t ip_total = 20 + 8 + udp_data_len;
|
||||
size_t reply_len = sizeof(eth_header) + ip_total;
|
||||
if (reply_len > sizeof(reply_buf)) continue;
|
||||
size_t ip_total = 20 + 8 + resp_len;
|
||||
size_t reply_len = sizeof(eth_header) + ip_total;
|
||||
|
||||
auto& rip = *reinterpret_cast<ipv4_header*>(reply_buf);
|
||||
rip.eth.dst = pkt.ip.eth.src;
|
||||
rip.eth.src = state.mac;
|
||||
rip.eth.ethertype = ETH_IPV4;
|
||||
rip.ver_ihl = 0x45;
|
||||
rip.dscp_ecn = 0;
|
||||
rip.total_len = __builtin_bswap16(ip_total);
|
||||
rip.identification = 0;
|
||||
rip.flags_frag = 0;
|
||||
rip.ttl = 64;
|
||||
rip.protocol = 17;
|
||||
rip.checksum = 0;
|
||||
rip.src = state.ip;
|
||||
rip.dst = pkt.ip.src;
|
||||
rip.checksum = ip_checksum(rip.ip_start(), 20);
|
||||
auto& rip = *reinterpret_cast<ipv4_header*>(tx_buf);
|
||||
rip.eth.dst = pkt.ip.eth.src;
|
||||
rip.eth.src = state.mac;
|
||||
rip.eth.ethertype = ETH_IPV4;
|
||||
rip.ver_ihl = 0x45;
|
||||
rip.dscp_ecn = 0;
|
||||
rip.total_len = __builtin_bswap16(ip_total);
|
||||
rip.identification = 0;
|
||||
rip.flags_frag = 0;
|
||||
rip.ttl = 64;
|
||||
rip.protocol = 17;
|
||||
rip.checksum = 0;
|
||||
rip.src = state.ip;
|
||||
rip.dst = pkt.ip.src;
|
||||
rip.checksum = ip_checksum(rip.ip_start(), 20);
|
||||
|
||||
auto& rudp = *reinterpret_cast<udp_header*>(reply_buf);
|
||||
rudp.src_port = PICOMAP_PORT;
|
||||
rudp.dst_port = pkt.src_port;
|
||||
rudp.length = __builtin_bswap16(8 + udp_data_len);
|
||||
rudp.checksum = 0;
|
||||
auto& rudp = *reinterpret_cast<udp_header*>(tx_buf);
|
||||
rudp.src_port = PICOMAP_PORT;
|
||||
rudp.dst_port = pkt.src_port;
|
||||
rudp.length = __builtin_bswap16(8 + resp_len);
|
||||
rudp.checksum = 0;
|
||||
|
||||
memcpy(reply_buf + sizeof(udp_header), resp.data(), udp_data_len);
|
||||
|
||||
send_raw(reply_buf, reply_len);
|
||||
}
|
||||
send_raw(tx_buf, reply_len);
|
||||
}
|
||||
|
||||
static void handle_icmp(const uint8_t* frame, size_t len) {
|
||||
|
||||
Reference in New Issue
Block a user