Skip to content

Commit

Permalink
Add random padding
Browse files Browse the repository at this point in the history
  • Loading branch information
hack3ric committed Oct 1, 2024
1 parent 39449c6 commit 144cd40
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 33 deletions.
9 changes: 6 additions & 3 deletions bpf/egress.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,15 @@ int egress_handler(struct __sk_buff* skb) {
__u16 payload_len = udp_len - sizeof(*udp);
__u32 seq = 0, ack_seq = 0, conn_cwnd;
__u32 random = bpf_get_prandom_u32();
__u32 padding;

bpf_spin_lock(&conn->lock);
if (likely(conn->state == CONN_ESTABLISHED)) {
seq = conn->seq;
ack_seq = conn->ack_seq;
conn->seq += payload_len + conn->settings.padding;
padding =
conn->settings.padding == PADDING_RANDOM ? (seq + ack_seq) % 11 : conn->settings.padding;
conn->seq += payload_len + padding;
} else {
if (conn->state == CONN_IDLE) {
__u32 cooldown = conn_cooldown(conn);
Expand Down Expand Up @@ -176,7 +179,7 @@ int egress_handler(struct __sk_buff* skb) {
conn_cwnd = conn->cwnd;
bpf_spin_unlock(&conn->lock);

size_t reserve_len = TCP_UDP_HEADER_DIFF + conn->settings.padding;
size_t reserve_len = TCP_UDP_HEADER_DIFF + padding;
if (ipv4) {
__be16 old_len = ipv4->tot_len;
__be16 new_len = htons(ntohs(old_len) + reserve_len);
Expand All @@ -192,7 +195,7 @@ int egress_handler(struct __sk_buff* skb) {
}

__be32 csum_diff = 0;
try_tc(mangle_data(skb, ip_end + sizeof(*udp), &csum_diff, conn->settings.padding));
try_tc(mangle_data(skb, ip_end + sizeof(*udp), &csum_diff, padding));
decl_shot(struct tcphdr, tcp, ip_end, skb);
update_tcp_header(tcp, payload_len, seq, ack_seq, conn_cwnd);

Expand Down
8 changes: 5 additions & 3 deletions bpf/ingress.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,10 @@ int ingress_handler(struct xdp_md* xdp) {
}
if (will_drop) return XDP_DROP;

size_t reserve_len = TCP_UDP_HEADER_DIFF + conn->settings.padding;
__u32 padding = conn->settings.padding == PADDING_RANDOM
? (ntohl(tcp->seq) + ntohl(tcp->ack_seq)) % 11
: conn->settings.padding;
size_t reserve_len = TCP_UDP_HEADER_DIFF + padding;
if (ipv4) {
__be16 old_len = ipv4->tot_len;
__be16 new_len = htons(ntohs(old_len) - reserve_len);
Expand All @@ -328,8 +331,7 @@ int ingress_handler(struct xdp_md* xdp) {
__u32 csum = (__u16)~ntohs(tcp->check);

__be32 csum_diff = 0;
try_xdp(restore_data(xdp, ip_end + sizeof(*tcp), ip_end + ip_payload_len, &csum_diff,
conn->settings.padding));
try_xdp(restore_data(xdp, ip_end + sizeof(*tcp), ip_end + ip_payload_len, &csum_diff, padding));
decl_drop(struct udphdr, udp, ip_end, xdp);
csum += u32_fold(ntohl(csum_diff));

Expand Down
3 changes: 2 additions & 1 deletion common/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ static inline void cleanup_malloc_str(char** ptr) { cleanup_malloc((void*)ptr);
#define MAX_PACKET_SIZE 10000

#define MAX_PADDING_LEN 16
#define PADDING_RANDOM (-127)

// Used for reading packet data in bulk
#define SEGMENT_SIZE 64
Expand Down Expand Up @@ -246,7 +247,7 @@ static const struct filter_settings FALLBACK_SETTINGS = {
static inline void filter_settings_apply(struct filter_settings* local,
const struct filter_settings* global) {
for (int i = 0; i < sizeof_array(local->array); i++)
if (local->array[i] < 0) local->array[i] = global->array[i];
if (local->array[i] == -1) local->array[i] = global->array[i];
}

struct conn_tuple {
Expand Down
48 changes: 26 additions & 22 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ int parse_handshake(char* str, struct filter_handshake* h) {
int nums[2];
try(parse_int_seq(str, nums, 2));
for (int i = 0; i < 2; i++)
if (nums[i] >= 0) h->array[i] = nums[i];
if (nums[i] != -1) h->array[i] = nums[i];
return 0;
}

Expand All @@ -140,11 +140,29 @@ int parse_keepalive(char* str, struct filter_keepalive* k) {
int nums[4];
try(parse_int_seq(str, nums, 4));
for (int i = 0; i < 4; i++)
if (nums[i] >= 0) k->array[i] = nums[i];
if (nums[i] != -1) k->array[i] = nums[i];
return 0;
}

int parse_padding(const char* str) { return parse_int_non_neg(str, 0, MAX_PADDING_LEN); }
int parse_padding(const char* str, __s16* padding) {
if (strcmp(str, "random") == 0)
*padding = PADDING_RANDOM;
else
*padding = try(parse_int_non_neg(str, 0, MAX_PADDING_LEN));
return 0;
}

static int parse_setting(const char* k, char* v, struct filter_settings* settings) {
if (strcmp("handshake", k) == 0)
try(parse_handshake(v, &settings->handshake));
else if (strcmp("keepalive", k) == 0)
try(parse_keepalive(v, &settings->keepalive));
else if (strcmp("padding", k) == 0)
try(parse_padding(v, &settings->padding));
else
return 0;
return 1;
}

int parse_filter(char* filter_str, struct filter* filters, struct filter_info* info, int size) {
int ret;
Expand Down Expand Up @@ -201,13 +219,7 @@ int parse_filter(char* filter_str, struct filter* filters, struct filter_info* i
next_delim = strchr(delim, ',');
if (next_delim) *next_delim = '\0';
try(parse_kv(delim, &k, &v));
if (strcmp("handshake", k) == 0)
try(parse_handshake(v, &info[0].settings.handshake));
else if (strcmp("keepalive", k) == 0)
try(parse_keepalive(v, &info[0].settings.keepalive));
else if (strcmp("padding", k) == 0)
info[0].settings.padding = try(parse_padding(v));
else
if (!try(parse_setting(k, v, &info[0].settings)))
ret(-EINVAL, _("unsupported option type: '%s'"), k);
if (!next_delim) break;
}
Expand Down Expand Up @@ -249,12 +261,6 @@ int parse_config_file(FILE* file, struct run_args* args) {
}
log_verbosity = parsed;

} else if (strcmp(k, "handshake") == 0) {
try(parse_handshake(v, &args->gsettings.handshake));
} else if (strcmp(k, "keepalive") == 0) {
try(parse_keepalive(v, &args->gsettings.keepalive));
} else if (strcmp(k, "padding") == 0) {
args->gsettings.padding = try(parse_padding(v));
} else if (strcmp(k, "filter") == 0) {
unsigned int fc = args->filter_count;
ret = parse_filter(v, &args->filters[fc], &args->info[fc], sizeof_array(args->filters) - fc);
Expand All @@ -265,7 +271,8 @@ int parse_config_file(FILE* file, struct run_args* args) {
return ret;
else
args->filter_count += ret;
} else {

} else if (!try(parse_setting(k, v, &args->gsettings))) {
ret(-EINVAL, _("unknown key '%s'"), k);
}
}
Expand Down Expand Up @@ -303,11 +310,7 @@ int parse_lock_file(FILE* file, struct lock_content* c) {
try(parse_int_any(v, &c->whitelist_id));
else if (strcmp(k, "conns_id") == 0)
try(parse_int_any(v, &c->conns_id));
else if (strcmp(k, "handshake") == 0)
try(parse_handshake(v, &c->settings.handshake));
else if (strcmp(k, "keepalive") == 0)
try(parse_keepalive(v, &c->settings.keepalive));
else
else if (!try(parse_setting(k, v, &c->settings)))
ret(-EINVAL, _("unknown key '%s'"), k);
}
if (!version_checked) ret(-EINVAL, _("no version found in lock file"));
Expand All @@ -324,5 +327,6 @@ int write_lock_file(int fd, const struct lock_content* c) {
try(dprintf(fd, "handshake=%d:%d\n", c->settings.h.i, c->settings.h.r));
try(dprintf(fd, "keepalive=%d:%d:%d:%d\n", c->settings.k.t, c->settings.k.i, c->settings.k.r,
c->settings.k.s));
try(dprintf(fd, "padding=%d", c->settings.padding));
return 0;
}
2 changes: 1 addition & 1 deletion src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct lock_content {

int parse_handshake(char* str, struct filter_handshake* h);
int parse_keepalive(char* str, struct filter_keepalive* k);
int parse_padding(const char* str);
int parse_padding(const char* str, __s16* padding);
int parse_filter(char* filter_str, struct filter* filters, struct filter_info* info, int size);
int parse_config_file(FILE* file, struct run_args* args);
int parse_lock_file(FILE* file, struct lock_content* c);
Expand Down
2 changes: 1 addition & 1 deletion src/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static inline error_t args_parse_opt(int key, char* arg, struct argp_state* stat
try(parse_keepalive(arg, &args->gsettings.keepalive));
break;
case 'p':
args->gsettings.padding = try(parse_padding(arg));
try(parse_padding(arg, &args->gsettings.padding));
break;
case 'F':
args->file = arg;
Expand Down
12 changes: 10 additions & 2 deletions src/show.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ int show_overview(int whitelist_fd, struct filter_settings* gs, int log_verbosit
if (LOG_ALLOW_INFO) fprintf(out, "%s%s " RESET, log_prefixes[2][0], log_prefixes[2][1]);
fprintf(out, _(" %ssettings:%s handshake %d:%d, keepalive %d:%d:%d:%d"), BOLD, RESET, gs->h.i,
gs->h.r, gs->k.t, gs->k.i, gs->k.r, gs->k.s);
if (gs->padding) fprintf(out, _(", padding %d"), gs->padding);
if (gs->padding == PADDING_RANDOM)
fprintf(out, _(", padding random"));
else if (gs->padding)
fprintf(out, _(", padding %d"), gs->padding);
fprintf(out, "\n");

char buf[FILTER_FMT_MAX_LEN];
Expand Down Expand Up @@ -88,7 +91,12 @@ int show_overview(int whitelist_fd, struct filter_settings* gs, int log_verbosit
if (i < 3) fprintf(out, ":");
}
}
if (a->padding != b->padding) fprintf(out, ",padding=%d", info.settings.padding);
if (a->padding != b->padding) {
if (info.settings.padding == PADDING_RANDOM)
fprintf(out, ",padding=random");
else
fprintf(out, ",padding=%d", info.settings.padding);
}
if (strlen(info.host) != 0) fprintf(out, _(" %s(resolved from %s)"), RESET GRAY, info.host);
fprintf(out, RESET "\n");
}
Expand Down

0 comments on commit 144cd40

Please sign in to comment.