mirror of https://github.com/Chizi123/dnscomp.git

Joel Grunbaum
2022-05-23 b79b3a7406bc87fc57f4280449d809afad18ae04
Fix alignment with clang-format
6 files modified
1 files added
152 ■■■■■ changed files
.clang-format 12 ●●●●● patch | view | raw | blame | history
dns.c 58 ●●●●● patch | view | raw | blame | history
dns.h 3 ●●●● patch | view | raw | blame | history
main.c 55 ●●●●● patch | view | raw | blame | history
servers.h 10 ●●●● patch | view | raw | blame | history
slist.c 14 ●●●● patch | view | raw | blame | history
slist.h patch | view | raw | blame | history
.clang-format
New file
@@ -0,0 +1,12 @@
---
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: AlignWithSpaces
AllowShortIfStatementsOnASingleLine: true
BreakBeforeBraces: Linux
PointerAlignment: Left
AllowShortIfStatementsOnASingleLine: true
IndentCaseBlocks: true
IndentCaseLabels: false
SortUsingDeclarations: true
dns.c
@@ -1,14 +1,14 @@
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
//#include <netint/in.h>
//#include <netdb.h>
//#include <sys/time.h>
#include "dns.h"
#include <time.h>
#include <unistd.h>
#include "dns.h"
void change_to_DNS_name_format(unsigned char* dns, unsigned char* host);
char* read_name(unsigned char* reader, unsigned char* buffer, int* count);
@@ -17,8 +17,7 @@
// https://gist.github.com/fffaraz/9d9170b57791c28ccda9255b48315168
/* DNS header struct */
struct DNS_HEADER
{
struct DNS_HEADER {
     unsigned short id;         //ID number
     unsigned char rd :1;       //recursion
     unsigned char tc :1;       //truncated message
@@ -37,23 +36,20 @@
};
/* structured for query structure */
struct QUESTION
{
struct QUESTION {
     unsigned short qtype;
     unsigned short qclass;
};
/* Query structure */
struct QUERY
{
struct QUERY {
     unsigned char* name;
     struct QUESTION* ques;
};
/* Constant sized fields of record structure */
#pragma pack(push, 1)
struct R_DATA
{
struct R_DATA {
     unsigned short type;
     unsigned short _class;
     unsigned int ttl;
@@ -62,8 +58,7 @@
#pragma pack(pop)
/* Pointers to record components */
struct RES_RECORD
{
struct RES_RECORD {
     char* name;
     struct R_DATA resource;
     char* rdata;
@@ -71,7 +66,8 @@
// Test server dns_ip as IPv4 string for hostname
// Writes received packet to buf, which is supplied and returns time for request
struct timespec resolve(unsigned char* buf, char* hostname, char* dns_ip, int query_type)
struct timespec resolve(unsigned char* buf, char* hostname, char* dns_ip,
                        int query_type)
{
     int s, i;
     struct sockaddr_in dest;
@@ -79,10 +75,15 @@
     struct DNS_HEADER* dns = (struct DNS_HEADER*)buf;
     struct QUESTION* qinfo;
     struct timespec start, end, total, timeout;
     timeout.tv_nsec=0; timeout.tv_sec=1;
    timeout.tv_nsec = 0;
    timeout.tv_sec = 1;
     s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
     setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timespec)); //use a 1 second timeout for receiving, should be more than enough and anything more is really bad
    setsockopt(
        s, SOL_SOCKET, SO_RCVTIMEO, &timeout,
        sizeof(struct timespec)); // use a 1 second timeout for receiving,
                                  // should be more than enough and anything
                                  // more is really bad
     dest.sin_family = AF_INET;
     dest.sin_port = htons(53);
     dest.sin_addr.s_addr = inet_addr(dns_ip);
@@ -107,20 +108,26 @@
     //dns packet query
     qname = (unsigned char*)&buf[sizeof(struct DNS_HEADER)];
     change_to_DNS_name_format(qname, (unsigned char*)hostname);
     qinfo = (struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + strlen((const char*)qname) + 1];
     qinfo->qtype = htons(query_type); //type of query from argument (A,AAAA,MX,CNAME,NS,...)
    qinfo = (struct QUESTION*)&buf[sizeof(struct DNS_HEADER) +
                                   strlen((const char*)qname) + 1];
    qinfo->qtype = htons(
        query_type); // type of query from argument (A,AAAA,MX,CNAME,NS,...)
     qinfo->qclass = htons(1); //internet class
     //send request
     // return less than 0 is a fail
     clock_gettime(CLOCK_MONOTONIC, &start);
     i = sendto(s,(char*)buf, sizeof(struct DNS_HEADER)+strlen((const char*)qname)+1+sizeof(struct QUESTION), 0, (struct sockaddr*)&dest, sizeof(dest));
    i = sendto(s, (char*)buf,
               sizeof(struct DNS_HEADER) + strlen((const char*)qname) + 1 +
                   sizeof(struct QUESTION),
               0, (struct sockaddr*)&dest, sizeof(dest));
     if (i < 0) {
          //receive response
          //negative return is a fail
          i = sizeof(dest);
          i = recvfrom(s, (char*)buf, 65536, 0, (struct sockaddr*)&dest, (socklen_t*)&i);
        i = recvfrom(s, (char*)buf, 65536, 0, (struct sockaddr*)&dest,
                     (socklen_t*)&i);
          clock_gettime(CLOCK_MONOTONIC, &end);
     }
@@ -137,7 +144,8 @@
     return total;
}
// Print dns packet content, not terribly reliable but works for testing resolve with A requests
// Print dns packet content, not terribly reliable but works for testing resolve
// with A requests
void print_packet(unsigned char* buf)
{
     struct RES_RECORD answers[20], auth[20], addit[20];
@@ -146,8 +154,11 @@
     unsigned char* qname = buf+sizeof(struct DNS_HEADER), *reader;
     int stop, i, j;
     dns = (struct DNS_HEADER*)buf;
     reader = &buf[sizeof(struct DNS_HEADER)+strlen((const char*)qname)+1+sizeof(struct QUESTION)];
     printf("Response contains %d Qs, %d ans, %d auth serv, %d add reconds\n", ntohs(dns->q_count), ntohs(dns->ans_count), ntohs(dns->auth_count), ntohs(dns->add_count));
    reader = &buf[sizeof(struct DNS_HEADER) + strlen((const char*)qname) + 1 +
                  sizeof(struct QUESTION)];
    printf("Response contains %d Qs, %d ans, %d auth serv, %d add reconds\n",
           ntohs(dns->q_count), ntohs(dns->ans_count), ntohs(dns->auth_count),
           ntohs(dns->add_count));
     stop = 0;
     //read answers
@@ -158,7 +169,8 @@
          reader = reader+sizeof(struct R_DATA);
          if (ntohs(answers[i].resource.type) == T_A) { //IPv4 address
               answers[i].rdata = (char*)malloc(ntohs(answers[i].resource.data_len));
            answers[i].rdata =
                (char*)malloc(ntohs(answers[i].resource.data_len));
               for (j = 0; j < ntohs(answers[i].resource.data_len); j++) {
                    answers[i].rdata[j] = reader[j];
               }
dns.h
@@ -8,5 +8,6 @@
#define T_TXT 16                // Text record
#define T_AAAA 28               // IPv6 address
struct timespec resolve(unsigned char* buf, char* hostname, char* dns_ip, int query_type);
struct timespec resolve(unsigned char* buf, char* hostname, char* dns_ip,
                        int query_type);
void print_packet(unsigned char* buf);
main.c
@@ -4,15 +4,15 @@
 * Tried to only use POSIX functions to ensure cross platform compatibility
 **/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include "dns.h"
#include "servers.h"
#include "slist.h"
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#define NUM_TESTS 10
@@ -21,8 +21,9 @@
void *print_progress(void *in);
// All global variables as passing to threads in structs caused corruption
// Variables are only modified before threads are created and as such are thread-safe
// tests_done is modified to provide a rough count of number of tests being completed for progress measurement
// Variables are only modified before threads are created and as such are
// thread-safe tests_done is modified to provide a rough count of number of
// tests being completed for progress measurement
int tests_done = 0, num_tests = NUM_TESTS, num_servers = NUM_DNS, num_hosts = 0;
struct hosts_list *hosts = NULL;
struct dns_list *servers = NULL;
@@ -53,8 +54,14 @@
            printf("Options:\n");
            printf("\t-s <server>\tadd a DNS server to be tested\n");
            printf("\t-a <hostname>\tadd a hostname to be tested\n");
            printf("\t-t <number>\tspecify the number of hostnames to be tested, capped at 50 + number manually added\n\t\t\tdefaults to test all available\n");
            printf("\t-n <number>\tspecify the number of tests to perform on each hostname\n\t\t\tdefaults to 10\n");
            printf(
                "\t-t <number>\tspecify the number of hostnames to be tested, "
                "capped at 50 + number manually added\n\t\t\tdefaults to test "
                "all "
                "available\n");
            printf(
                "\t-n <number>\tspecify the number of tests to perform on each "
                "hostname\n\t\t\tdefaults to 10\n");
            printf("\t-h\t\tShow this help\n");
            free_dns_list(&servers);
            free_hosts_list(&hosts);
@@ -79,7 +86,8 @@
}
// Test each dns server individually
// Each test runs in its own thread and results are written to the respective dns_list
// Each test runs in its own thread and results are written to the respective
// dns_list
int test_dns(void)
{
    struct dns_list *curr = servers;
@@ -106,21 +114,25 @@
{
    unsigned long long avg_nsec = 0;
    struct dns_list *dns = (struct dns_list *)in;
    dns->time.tv_sec = 0; dns->time.tv_nsec = 0;
    dns->time.tv_sec = 0;
    dns->time.tv_nsec = 0;
    for (int i = 0; i < num_tests; i++) {
        struct hosts_list *curr = hosts;
        while (curr) {
            struct timespec run;
            run.tv_sec = -1; run.tv_nsec = 0;
            run.tv_sec = -1;
            run.tv_nsec = 0;
            unsigned char buf[65536];
            for (int j = 0; j < 3 && run.tv_sec == -1; j++) {
                run = resolve(buf, curr->server, dns->server, T_A);
            }
            if (run.tv_sec == -1) //if test has failed 3 times, set time taken to 3s as penalty
            if (run.tv_sec == -1) // if test has failed 3 times, set time taken
                                  // to 3s as penalty
                run.tv_sec = 3;
            dns->time.tv_sec += run.tv_sec;
            dns->time.tv_nsec += run.tv_nsec;
            if (dns->time.tv_nsec >= 1000000000) { //nanoseconds have overflowed into seconds
            if (dns->time.tv_nsec >=
                1000000000) { // nanoseconds have overflowed into seconds
                dns->time.tv_sec += 1;
                dns->time.tv_nsec -= 1000000000;
            }
@@ -128,20 +140,25 @@
            curr = curr->next;
        }
    }
    avg_nsec = 1000000000*(dns->time.tv_sec%(num_hosts*num_tests))+dns->time.tv_nsec;
    avg_nsec = 1000000000 * (dns->time.tv_sec % (num_hosts * num_tests)) +
               dns->time.tv_nsec;
    dns->time.tv_sec = dns->time.tv_sec/(num_hosts*num_tests);
    dns->time.tv_nsec = avg_nsec/(num_hosts*num_tests);
    return NULL;
}
// Prints the progress every 0.1s for an indication of speed
// tests_done is being written to in parallel, so may be overwritten but serves as a decent estimate of the progress
// tests_done is being written to in parallel, so may be overwritten but serves
// as a decent estimate of the progress
void *print_progress(void *in)
{
    struct timespec s;
    s.tv_sec = 0; s.tv_nsec = 100000000;
    s.tv_sec = 0;
    s.tv_nsec = 100000000;
    while (1) {
        printf("\r%.2f%% done", ((float)tests_done)/(num_servers*num_hosts*num_tests) * 100);
        printf("\r%.2f%% done", ((float)tests_done) /
                                    (num_servers * num_hosts * num_tests) *
                                    100);
        fflush(stdout);
        nanosleep(&s, NULL);
    }
servers.h
@@ -1,9 +1,9 @@
/**
 * Unfortunately, wanting to make cross platform required static lists of hosts and dns servers
 * At least until I think of a good way to do it
 * Hosts came from alexa top 50 one day and dns are from quick searching for common servers
 * DNS only takes IPv4 server addresses
 * The definitions must be the same as the size of the arrays, as they are required later on to be read properly
 * Unfortunately, wanting to make cross platform required static lists of hosts
 *and dns servers At least until I think of a good way to do it Hosts came from
 *alexa top 50 one day and dns are from quick searching for common servers DNS
 *only takes IPv4 server addresses The definitions must be the same as the size
 *of the arrays, as they are required later on to be read properly
 **/
#define NUM_HOSTNAMES 50
slist.c
@@ -1,6 +1,6 @@
#include "slist.h"
#include <stdio.h>
#include <stdlib.h>
#include "slist.h"
void split(struct dns_list *head, struct dns_list **a, struct dns_list **b);
struct dns_list *merge(struct dns_list *a, struct dns_list *b);
@@ -50,7 +50,8 @@
     }
     end->next = NULL;
     end->server = server;
     end->time.tv_nsec = 0; end->time.tv_sec = 0;
    end->time.tv_nsec = 0;
    end->time.tv_sec = 0;
     return 0;
}
@@ -99,10 +100,8 @@
struct dns_list *merge(struct dns_list *a, struct dns_list *b)
{
    struct dns_list *out = NULL;
    if (!a)
        return b;
    if (!b)
        return a;
    if (!a) return b;
    if (!b) return a;
    if (comp_times(a->time, b->time) > 0) {
        out = b;
@@ -131,7 +130,8 @@
{
    printf("%-20s | %s\n", "Server", "Time");
    while (head) {
        printf("%-20s | %ld.%09ld\n", head->server, head->time.tv_sec, head->time.tv_nsec);
        printf("%-20s | %ld.%09ld\n", head->server, head->time.tv_sec,
               head->time.tv_nsec);
        head = head->next;
    }
    return 0;
slist.h