Add semifunctional check endpoint
This commit is contained in:
parent
930108dec2
commit
e89075bd0d
4 changed files with 121 additions and 16 deletions
|
@ -4,9 +4,16 @@ import sys
|
|||
import time
|
||||
|
||||
op = sys.argv[1]
|
||||
rest = " ".join(sys.argv[2:])
|
||||
rest = sys.argv[2:]
|
||||
|
||||
sys.stdout.write(op.decode())
|
||||
sys.stdout.write(struct.pack("b", len(rest)).decode())
|
||||
sys.stdout.write(rest)
|
||||
if op == "C":
|
||||
payload = "\0".join(rest)
|
||||
else:
|
||||
payload = " ".join(rest)
|
||||
|
||||
print(payload.encode(), file=sys.stderr)
|
||||
|
||||
sys.stdout.write(op)
|
||||
sys.stdout.write(struct.pack("b", len(payload)).decode())
|
||||
sys.stdout.write(payload)
|
||||
sys.stdout.flush()
|
||||
|
|
|
@ -7,22 +7,24 @@
|
|||
#include <stdio.h>
|
||||
#include "persist.c"
|
||||
|
||||
#define EINVALIDRULE 2
|
||||
|
||||
// Functions in this file return zero if successful or non-zero otherwise.
|
||||
#define HANDLER_OK 0
|
||||
#define HANDLER_REJECTED 1
|
||||
#define HANDLER_INVRULE 2
|
||||
#define HANDLER_ILLEGALARG 3
|
||||
#define HANDLER_FOUND 4
|
||||
|
||||
int handle_add_rule(char *data, size_t len) {
|
||||
// Add rule should provide a rule as per exercise 1 definitions.
|
||||
int retval = 0;
|
||||
int retval = HANDLER_OK;
|
||||
struct Rule *parse_res = (struct Rule*)malloc(sizeof(struct Rule));
|
||||
|
||||
char *eptr = parse_rule(data, parse_res);
|
||||
if (eptr == NULL) {
|
||||
retval = EINVALIDRULE;
|
||||
retval = HANDLER_INVRULE;
|
||||
goto end;
|
||||
} else if ((eptr - data) != len) {
|
||||
// This means we've not consumed everything which means that there's extraneous data?
|
||||
retval = EINVALIDRULE;
|
||||
retval = HANDLER_INVRULE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
@ -30,4 +32,30 @@ int handle_add_rule(char *data, size_t len) {
|
|||
end:
|
||||
free_rule(parse_res);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int handle_check_rule(char *data, size_t len) {
|
||||
// Check if the specified IP and port is matched by any IP and port
|
||||
struct IP ip;
|
||||
Port port;
|
||||
|
||||
char* endptr = parse_ip(data, &ip);
|
||||
if (endptr == NULL) {
|
||||
return HANDLER_ILLEGALARG;
|
||||
} else if (endptr[-1] != '\0') {
|
||||
return HANDLER_ILLEGALARG;
|
||||
}
|
||||
|
||||
endptr = parse_port(endptr, &port);
|
||||
if (endptr == NULL) {
|
||||
return HANDLER_ILLEGALARG;
|
||||
} else if ((endptr - data) != len) {
|
||||
return HANDLER_ILLEGALARG;
|
||||
}
|
||||
|
||||
if (check_ip_and_port(&ip, port) == 0) {
|
||||
return HANDLER_REJECTED;
|
||||
}
|
||||
|
||||
return HANDLER_OK;
|
||||
}
|
|
@ -18,11 +18,11 @@ struct Frame {
|
|||
struct LogFrame *log;
|
||||
};
|
||||
|
||||
struct Frame* head = NULL;
|
||||
pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
struct Frame* persist_head = NULL;
|
||||
pthread_rwlock_t persist_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
struct Frame** get_last_frame() {
|
||||
struct Frame** cursor = &head;
|
||||
struct Frame** cursor = &persist_head;
|
||||
while (1) {
|
||||
if (*cursor == NULL) {
|
||||
break;
|
||||
|
@ -35,8 +35,23 @@ struct Frame** get_last_frame() {
|
|||
return cursor;
|
||||
}
|
||||
|
||||
void append_frame(struct LogFrame **log, struct IP *ip, Port port) {
|
||||
struct LogFrame *new_log_frame = (struct LogFrame*) malloc(sizeof(struct LogFrame));
|
||||
memset(new_log_frame, 0, sizeof(struct LogFrame));
|
||||
|
||||
if (*log == NULL) {
|
||||
*log = new_log_frame;
|
||||
} else {
|
||||
struct LogFrame **cursor = log;
|
||||
while ((*cursor)->next != NULL) {
|
||||
cursor = &((*cursor)->next);
|
||||
}
|
||||
(*cursor)->next = new_log_frame;
|
||||
}
|
||||
}
|
||||
|
||||
void add_frame(struct Rule* rule) {
|
||||
pthread_rwlock_wrlock(&lock);
|
||||
pthread_rwlock_wrlock(&persist_lock);
|
||||
struct Frame** last_frame = get_last_frame();
|
||||
|
||||
struct Frame* new_frame = (struct Frame*) malloc(sizeof(struct Frame));
|
||||
|
@ -49,5 +64,49 @@ void add_frame(struct Rule* rule) {
|
|||
}
|
||||
|
||||
new_frame->rule = *rule;
|
||||
pthread_rwlock_unlock(&lock);
|
||||
pthread_rwlock_unlock(&persist_lock);
|
||||
}
|
||||
|
||||
int check_ip_and_port(struct IP *ip, Port port) {
|
||||
// TODO: Something here is broken wrt. ranges of ports and maybe IPs.
|
||||
|
||||
pthread_rwlock_wrlock(&persist_lock);
|
||||
|
||||
struct Frame *cursor = persist_head;
|
||||
if (cursor == NULL) {
|
||||
goto not_found;
|
||||
}
|
||||
|
||||
while (cursor != NULL) {
|
||||
struct Rule *r = &(cursor->rule);
|
||||
|
||||
int ip_matches = 0;
|
||||
int port_matches = 0;
|
||||
|
||||
if ((r->ip.end != NULL && compare_ip(ip, &r->ip.start) > -1 &&
|
||||
compare_ip(ip, r->ip.end) < 1) ||
|
||||
compare_ip(ip, &r->ip.start) == 0) {
|
||||
ip_matches = 1;
|
||||
}
|
||||
|
||||
if ((r->port.end != NULL && akpa_numcmp(port, r->port.start) > -1 &&
|
||||
akpa_numcmp(port, *r->port.end) < 1) ||
|
||||
akpa_numcmp(port, r->port.start) == 0) {
|
||||
port_matches = 1;
|
||||
}
|
||||
|
||||
if (ip_matches == 1 && port_matches == 1) {
|
||||
append_frame(&cursor->log, ip, port);
|
||||
goto found;
|
||||
}
|
||||
|
||||
cursor = cursor->next;
|
||||
}
|
||||
|
||||
not_found:
|
||||
pthread_rwlock_unlock(&persist_lock);
|
||||
return 0;
|
||||
found:
|
||||
pthread_rwlock_unlock(&persist_lock);
|
||||
return 1;
|
||||
}
|
|
@ -117,13 +117,24 @@ void handle_connection(int *sdptr) {
|
|||
switch (operation) {
|
||||
case 'A': {
|
||||
int status = handle_add_rule(data, message_length);
|
||||
if (status != 0) {
|
||||
if (status != HANDLER_OK) {
|
||||
response = "Invalid rule";
|
||||
} else {
|
||||
response = "Rule added";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'C': {
|
||||
int status = handle_check_rule(data, message_length);
|
||||
if (status == HANDLER_ILLEGALARG) {
|
||||
response = "Illegal IP address or port specified";
|
||||
} else if (status == HANDLER_REJECTED) {
|
||||
response = "Connection rejected";
|
||||
} else {
|
||||
response = "Connection accepted";
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
response = "Illegal request";
|
||||
break;
|
||||
|
|
Reference in a new issue