tor_multipath_voip/src/capture_traffic.c

92 lines
2.3 KiB
C

#include "capture_traffic.h"
void dynbuf_init(struct dynbuf* db) {
db->content = malloc(MEGABYTE);
if (db->content == NULL) {
perror("malloc dynbuf failed");
exit(EXIT_FAILURE);
}
db->written = 0;
db->alloced = MEGABYTE;
}
void dynbuf_check_alloc(struct dynbuf* db, size_t len) {
if (db->written + len > db->alloced) {
size_t new_alloced = db->written + len > 2 * db->alloced ? db->written + len : 2 * db->alloced;
db->content = realloc(db->content, new_alloced);
if (db->content == NULL) {
perror("realloc dynbuf failed");
exit(EXIT_FAILURE);
}
db->alloced = new_alloced;
}
}
void dynbuf_append(struct dynbuf* db, char* ptr, size_t len) {
dynbuf_check_alloc(db, len);
memcpy(db->content + db->written, ptr, len);
db->written += len;
}
void dynbuf_destroy(struct dynbuf* db) {
free(db->content);
}
void traffic_capture_init(struct capture_ctx* ctx, char* filename) {
ctx->activated = filename == NULL ? 0 : 1;
if (!ctx->activated) return;
ctx->filename = strdup(filename);
dynbuf_init (&ctx->in);
dynbuf_init (&ctx->out);
}
void traffic_capture_notify(struct capture_ctx* ctx, struct buffer_packet *bp, char* dest) {
if (!ctx->activated) return;
if (clock_gettime(CLOCK_MONOTONIC, &bp->seen) == -1){
perror("clock_gettime error");
exit(EXIT_FAILURE);
}
dynbuf_append (
strcmp(dest, "in") == 0 ? &ctx->in : &ctx->out,
(char*)bp,
sizeof(struct buffer_packet));
}
void traffic_capture_stop(struct capture_ctx* ctx) {
if (!ctx->activated) return;
FILE* fd = NULL;
char *exts[] = {"emitted", "received"};
struct dynbuf *dbs[] = {&ctx->in, &ctx->out};
for (int i = 0; i < 2; i++) {
size_t written = 0, ack = 0;
char *out_file = NULL;
asprintf(&out_file, "%s.%s", ctx->filename, exts[i]);
if (out_file == NULL || (fd = fopen(out_file, "w")) == NULL) {
perror("failed to open file");
exit(EXIT_FAILURE);
}
free(out_file);
while (written < dbs[i]->written) {
ack = fwrite(dbs[i]->content+written, sizeof(char), dbs[i]->written, fd);
if (ack <= 0) {
perror("unable to write capture file");
exit(EXIT_FAILURE);
}
written += ack;
}
fclose(fd);
dynbuf_destroy (dbs[i]);
}
free(ctx->filename);
}