Skip to content

Instantly share code, notes, and snippets.

@TCY16
Last active October 5, 2020 13:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TCY16/d918616d8470216f35a47e58764d4c2a to your computer and use it in GitHub Desktop.
Save TCY16/d918616d8470216f35a47e58764d4c2a to your computer and use it in GitHub Desktop.
static __always_inline
int do_rate_limit(struct udphdr *udp, struct dnshdr *dns, struct bucket *b)
{
// increment number of packets
b->n_packets++;
// get the current and elapsed time
uint64_t now = bpf_ktime_get_ns();
uint64_t elapsed = now - b->start_time;
// make sure the elapsed time is set and not outside of the frame
if (b->start_time == 0 || elapsed >= FRAME_SIZE)
{
// start new time frame
b->start_time = now;
b->n_packets = 0;
}
// less QPS than the threshold? Then pass.
if (b->n_packets < THRESHOLD)
return 1;
// save the old header values for checksum update later on
uint16_t old_val = dns->flags.as_value;
// change the DNS flags
dns->flags.as_bits_and_pieces.ad = 0; // not authentic data
dns->flags.as_bits_and_pieces.qr = 1; // query response
dns->flags.as_bits_and_pieces.tc = 1; // return over TCP
// change the UDP destination to the source
udp->dest = udp->source;
udp->source = __bpf_htons(DNS_PORT);
// calculate and write the new checksum
update_checksum(&udp->check, old_val, dns->flags.as_value);
// return as response
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment