Skip to content

Commit 7fa97aa

Browse files
authored
Merge pull request #26 from lil-skelly:crc-check
Implemented fraction verification via CRC-32
2 parents d4c7a41 + 8dd9698 commit 7fa97aa

File tree

9 files changed

+244
-146
lines changed

9 files changed

+244
-146
lines changed

client/client

23.1 KB
Binary file not shown.

client/include/crc32.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <stdint.h>
55
#include <stdlib.h>
6-
6+
#include "fraction.h"
77
extern const uint32_t crc32_tab[];
88
/*
99
* A function that calculates the CRC-32 based on the table above is
@@ -12,5 +12,4 @@ extern const uint32_t crc32_tab[];
1212
* in sys/libkern.h, where it can be inlined.
1313
*/
1414
uint32_t crc32(const void *buf, size_t size);
15-
1615
#endif // CRC32_H

client/include/fraction.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@ typedef struct {
1616
uint32_t magic;
1717
uint32_t index;
1818
char iv[16];
19-
uint32_t crc;
2019

20+
uint32_t crc;
21+
22+
size_t data_size;
2123
char *data;
2224
} fraction_t;
2325

2426
int download_fraction(int sfd, char *url, fraction_t *fraction);
25-
int fraction_parse(char *data, size_t size, fraction_t *fraction);
27+
int fraction_parse(char *data, size_t size, fraction_t *fraction);
2628
int check_magic(uint32_t data);
2729
void print_fraction(fraction_t fraction);
2830
void fraction_free(fraction_t *fraction);
2931
int compare_fractions(const void* a, const void* b);
32+
int check_fractions(fraction_t *fraction, size_t size);
3033
#endif

client/src/crc32.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "../include/crc32.h"
2+
#include "../include/fraction.h"
23

34
const uint32_t crc32_tab[] = {
45
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
@@ -54,3 +55,4 @@ uint32_t crc32(const void *buf, size_t size) {
5455
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
5556
return crc ^ ~0U;
5657
}
58+

client/src/fraction.c

Lines changed: 74 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,54 @@
11
#include "../include/fraction.h"
2-
#include <stdint.h>
2+
#include "../include/crc32.h"
33

4-
5-
// Change the return type to int to indicate success or failure
64
int download_fraction(int sfd, char *url, fraction_t *fraction) {
75
char *path = NULL;
86
http_res_t res;
9-
fraction_t downloaded_fraction = {}; // Initialize to zero in case of failure
7+
fraction_t downloaded_fraction = {};
108

119
// Parse the URL to get the path
1210
path = get_path_from_url(url);
1311
if (!path) {
1412
fprintf(stderr, "Invalid URL: %s\n", url);
15-
return 1; // Return failure
13+
return 1;
1614
}
1715

1816
// Perform the HTTP GET request
1917
if (http_get(sfd, path, &res) != HTTP_SUCCESS) {
2018
fprintf(stderr, "Failed to download: %s\n", url);
21-
return 1; // Return failure
19+
return 1;
2220
}
2321

2422
// Parse the downloaded data into a fraction
2523
if (fraction_parse(res.data, res.size, &downloaded_fraction) != 0) {
26-
http_free(&res); // Free HTTP response
27-
return 1; // Return failure
24+
http_free(&res);
25+
return 1;
2826
}
2927

30-
// If the user provided a fraction pointer, copy the result
31-
if (fraction) {
32-
*fraction = downloaded_fraction;
33-
}
28+
*fraction = downloaded_fraction;
29+
3430

3531
// Cleanup
3632
http_free(&res);
3733

38-
return 0; // Return success
34+
return 0;
3935
}
4036

4137
int fraction_parse(char *data, size_t size, fraction_t *fraction) {
38+
const size_t UINT32_SIZE = sizeof(uint32_t);
4239
const size_t IV_SIZE = 16; // 16 bytes for the IV
43-
const size_t MAGIC_SIZE = sizeof(uint32_t);
44-
const size_t INDEX_SIZE = sizeof(uint32_t);
45-
const size_t CRC_SIZE = sizeof(uint32_t);
40+
const size_t MAGIC_SIZE = UINT32_SIZE;
41+
const size_t INDEX_SIZE = UINT32_SIZE;
42+
const size_t CRC_SIZE = UINT32_SIZE;
4643
const size_t HEADER_SIZE = MAGIC_SIZE + INDEX_SIZE + IV_SIZE + CRC_SIZE;
44+
size_t data_size;
4745

4846
// Ensure the data size is sufficient
4947
if (size < HEADER_SIZE) {
50-
return 1; // Failure: data size is too small
51-
}
48+
fprintf(stderr, "Insufficient size: %lu\n", size);
49+
return 1;
50+
51+
}
5252

5353
// Extract fields from data buffer with endianess handling
5454
uint32_t magic, index, crc;
@@ -57,33 +57,27 @@ int fraction_parse(char *data, size_t size, fraction_t *fraction) {
5757
memcpy(fraction->iv, data + MAGIC_SIZE + INDEX_SIZE, IV_SIZE);
5858
memcpy(&crc, data + MAGIC_SIZE + INDEX_SIZE + IV_SIZE, CRC_SIZE);
5959

60-
// Convert from little-endian to host byte order if needed (for
61-
// little-endian systems, this is usually not required)
62-
magic = __bswap_32(magic);
63-
index = __bswap_32(index);
64-
crc = __bswap_32(crc);
65-
66-
// Set the extracted values in the fraction structure
67-
fraction->magic = magic;
68-
fraction->index = index;
69-
fraction->crc = crc;
70-
7160
// Check the magic number
72-
if (!check_magic(fraction->magic)) {
73-
return 1; // Failure: magic number does not match
61+
if (!check_magic(magic)) {
62+
fprintf(stderr, "Wrong magic number: %02x\n", magic);
63+
return 1;
7464
}
7565

7666
// Allocate memory for fraction data
77-
size_t data_size = size - HEADER_SIZE;
67+
data_size = size - HEADER_SIZE;
7868
fraction->data = malloc(data_size);
7969
if (!fraction->data) {
80-
return 1; // Failure: memory allocation error
70+
fprintf(stderr, "Failed to allocate data for fraction\n");
71+
return 1;
8172
}
82-
83-
// Copy the remaining data
73+
// Set the extracted values in the fraction structure
74+
fraction->magic = magic;
75+
fraction->index = index;
76+
fraction->crc = crc;
77+
fraction->data_size = data_size;
8478
memcpy(fraction->data, data + HEADER_SIZE, data_size);
8579

86-
return 0; // Success
80+
return 0;
8781
}
8882

8983
int check_magic(uint32_t magic) {
@@ -101,12 +95,52 @@ int compare_fractions(const void *a, const void *b) {
10195
void print_fraction(fraction_t fraction) {
10296
printf("Magic: 0x%08x\n", fraction.magic);
10397
printf("Index: %u\n", fraction.index);
104-
printf("CRC: 0x%08x\n", fraction.crc);
10598
printf("IV: ");
10699
for (size_t i = 0; i < sizeof(fraction.iv); i++) {
107100
printf("%02x ", (unsigned char)fraction.iv[i]);
108101
}
109-
printf("\n\n");
102+
printf("\n");
103+
printf("CRC-32: 0x%08x\n", fraction.crc);
104+
printf("Data size: %lu\n\n", fraction.data_size);
105+
}
106+
107+
int calc_crc(fraction_t *frac){
108+
uint8_t buffer[sizeof(frac->magic) + sizeof(frac->index) + sizeof(frac->iv) + frac->data_size];
109+
size_t offset = 0;
110+
111+
memcpy(buffer + offset, &frac->magic, sizeof(frac->magic));
112+
offset += sizeof(frac->magic);
113+
114+
memcpy(buffer + offset, &frac->index, sizeof(frac->index));
115+
offset += sizeof(frac->index);
116+
117+
memcpy(buffer + offset, frac->iv, sizeof(frac->iv));
118+
offset += sizeof(frac->iv);
119+
120+
memcpy(buffer + offset, frac->data, frac->data_size);
121+
offset += frac->data_size;
122+
123+
uint32_t calculated_crc = crc32(buffer, offset);
124+
125+
if (calculated_crc != frac->crc) {
126+
printf("Checksum incorrect\n");
127+
printf("Checksum generated: %08X\n", calculated_crc);
128+
printf("Checksum from fraction: %08X\n\n", frac->crc);
129+
}
130+
131+
return calculated_crc == frac->crc;
132+
}
133+
134+
int check_fractions(fraction_t *fraction, size_t size){
135+
int res = 0;
136+
for(size_t i = 0; i < size; i++){
137+
if (!calc_crc(&fraction[i])) {
138+
fprintf(stderr, "Failed to validate integrity of fraction:\n");
139+
print_fraction(fraction[i]);
140+
res += 1;
141+
}
142+
}
143+
return res;
110144
}
111145

112146
void fraction_free(fraction_t *fraction) {
@@ -115,3 +149,5 @@ void fraction_free(fraction_t *fraction) {
115149
fraction->index = 0;
116150
fraction->crc = 0;
117151
}
152+
153+

client/src/main.c

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,103 +7,128 @@
77
#include "../include/sock.h"
88
#include "../include/utils.h"
99

10-
/* Networking constants */
1110
#define SERVER_IP "127.0.0.1"
1211
#define SERVER_PORT "8000"
1312

13+
/* Helper functions to assist with cleanup, I hate cleanup */
14+
static void cleanup_char_array(char **array, int n_elem) {
15+
for (int i = 0; i < n_elem; i++) {
16+
free(array[i]);
17+
}
18+
free(array);
19+
}
20+
21+
static void cleanup_fraction_array(fraction_t *array, int n_elem) {
22+
for (int i = 0; i < n_elem; i++) {
23+
fraction_free(&array[i]);
24+
}
25+
free(array);
26+
}
27+
1428
int main(void) {
1529
struct addrinfo hints, *ainfo;
16-
int sfd; // socket file descriptor
30+
int sfd = -1; // to be extra professional
1731
http_res_t http_fraction_res, http_post_res;
32+
char **fraction_links = NULL;
33+
fraction_t *fractions = NULL;
1834

19-
/* Setup socket and initiate connection with the server */
2035
setup_hints(&hints);
2136

2237
if (h_getaddrinfo(SERVER_IP, SERVER_PORT, &hints, &ainfo) != 0) {
2338
fprintf(stderr, "Failed to resolve server address\n");
2439
return EXIT_FAILURE;
2540
}
2641

27-
2842
printf("Connecting to: %s:%s\n", SERVER_IP, SERVER_PORT);
2943
sfd = create_sock_and_conn(ainfo);
44+
freeaddrinfo(ainfo);
3045
if (sfd == -1) {
3146
fprintf(stderr, "Failed to create socket and connect\n");
3247
return EXIT_FAILURE;
3348
}
34-
freeaddrinfo(ainfo); // ainfo no longer needed
3549

36-
/* Get the fraction links */
3750
if (http_get(sfd, "/", &http_fraction_res) != HTTP_SUCCESS) {
3851
fprintf(stderr, "Failed to retrieve fraction links\n");
39-
goto cleanup_socket;
52+
goto cleanup;
4053
}
4154

42-
// Count number of links
4355
int num_links = count_lines(http_fraction_res.data) + 1;
44-
45-
// Allocate memory for fraction links
46-
char **fraction_links = malloc(num_links * sizeof(char *));
56+
fraction_links = malloc(num_links * sizeof(char *));
4757
if (!fraction_links) {
4858
fprintf(stderr, "Failed to allocate memory for fraction links\n");
4959
http_free(&http_fraction_res);
50-
goto cleanup_socket;
60+
goto cleanup;
5161
}
5262

53-
// Split the response data into lines
5463
int lines_read =
5564
split_fraction_links(http_fraction_res.data, fraction_links, num_links);
5665
if (lines_read < 0) {
5766
fprintf(stderr, "Failed to split fraction links\n");
58-
free(fraction_links);
67+
cleanup_char_array(fraction_links, num_links);
5968
http_free(&http_fraction_res);
60-
goto cleanup_socket;
69+
goto cleanup;
6170
}
6271

63-
// Storing the fractions in a array
64-
fraction_t *fractions = malloc(lines_read * sizeof(fraction_t));
65-
if (fractions == NULL) {
66-
fprintf(stderr, "Failed to malloc memory for fractions\n");
72+
73+
fractions = malloc(lines_read * sizeof(fraction_t));
74+
if (!fractions) {
75+
fprintf(stderr, "Failed to allocate memory for fractions\n");
76+
cleanup_char_array(fraction_links, num_links);
77+
http_free(&http_fraction_res);
78+
http_free(&http_post_res);
79+
goto cleanup;
6780
}
6881

69-
for (int i=0; i<lines_read; i++) {
82+
for (int i = 0; i < lines_read; i++) {
7083
if (download_fraction(sfd, fraction_links[i], &fractions[i]) != 0) {
71-
fprintf(stderr, "Failed to parse fraction\n");
84+
fprintf(stderr, "Failed to download fraction\n");
7285
}
7386
}
74-
75-
// Sort the fractions based on index
87+
puts("Downloaded fractions");
7688
qsort(fractions, lines_read, sizeof(fraction_t), compare_fractions);
77-
for (int i = 0; i < lines_read; i++) {
78-
print_fraction(fractions[i]);
89+
90+
if (check_fractions(fractions, lines_read)) { // if this works, s0s4 and skelly is to blame!
91+
fprintf(stderr, "Fractions check failed\n");
92+
cleanup_char_array(fraction_links, num_links);
93+
cleanup_fraction_array(fractions, lines_read);
94+
http_free(&http_fraction_res);
95+
http_free(&http_post_res);
96+
goto cleanup;
7997
}
98+
puts("Verified fractions");
8099

81-
/* Notify the server that we successfully downloaded the fractions */
82100
if (http_post(sfd, "/deadbeef", "plain/text", "{'downloaded':true}",
83101
&http_post_res) != HTTP_SUCCESS) {
84102
fprintf(stderr, "Failed to send POST request\n");
85-
free(fraction_links);
103+
cleanup_char_array(fraction_links, num_links);
86104
http_free(&http_fraction_res);
87-
http_free(&http_post_res);
88-
goto cleanup_socket;
105+
goto cleanup;
89106
}
90107

91-
/* Cleanup */
92108
http_free(&http_fraction_res);
93109
http_free(&http_post_res);
94-
95-
// Free fractions and links
96-
for (int i = 0; i < lines_read; i++) {
97-
free(fraction_links[i]);
98-
fraction_free(&fractions[i]);
99-
}
100-
free(fraction_links);
101-
free(fractions);
110+
cleanup_char_array(fraction_links, num_links);
111+
cleanup_fraction_array(fractions, lines_read);
102112

103113
close(sfd);
104114
return EXIT_SUCCESS;
105115

106-
cleanup_socket:
107-
close(sfd);
116+
/* There's nothing to see here, move on*/
117+
cleanup: // we accept NO comments on this. have a !nice day
118+
if (sfd != -1) {
119+
close(sfd);
120+
}
121+
if (fraction_links) {
122+
cleanup_char_array(fraction_links, num_links);
123+
}
124+
if (fractions) {
125+
cleanup_fraction_array(fractions, num_links);
126+
}
127+
if (http_fraction_res.data) {
128+
http_free(&http_fraction_res);
129+
}
130+
if (http_post_res.data) {
131+
http_free(&http_post_res);
132+
}
108133
return EXIT_FAILURE;
109134
}

0 commit comments

Comments
 (0)