Browse Source

fixed some bugs in the relay code

cecylia 9 years ago
parent
commit
9589c7af93
4 changed files with 108 additions and 10 deletions
  1. 3 3
      server/Makefile
  2. 5 0
      server/flow.c
  3. 2 0
      server/flow.h
  4. 98 7
      server/relay.c

+ 3 - 3
server/Makefile

@@ -1,4 +1,4 @@
-CFLAGS=-g -Wall -std=gnu99
+CFLAGS=-g -ggdb -Wall -std=gnu99
 
 TARGETS=slitheen-proxy
 
@@ -7,10 +7,10 @@ all: $(TARGETS)
 slitheen-proxy.o flow.o rserv.o ptwist168.o util.o crypto.o relay.o:: ptwist.h rserv.h flow.h slitheen.h util.h crypto.h relay.h
 
 rserv: rserv.o ptwist168.o
-	gcc -g -o $@ $^ -lssl -lcrypto
+	gcc -g -ggdb -o $@ $^ -lssl -lcrypto
 
 slitheen-proxy: slitheen-proxy.o flow.o rserv.o ptwist168.o crypto.o relay.o relay.h crypto.h ptwist.h rserv.h flow.h slitheen.h
-	gcc -g -o $@ $^ -I/home/slitheen/Documents/include/openssl libssl.a libcrypto.a -lpcap -lpthread -ldl
+	gcc -g -ggdb -o $@ $^ -I/home/slitheen/Documents/include/openssl libssl.a libcrypto.a -lpcap -lpthread -ldl
 
 clean:
 	-rm *.o

+ 5 - 0
server/flow.c

@@ -48,6 +48,8 @@ flow *add_flow(flow newFlow) {
 	newFlow.current_session = NULL;
 	newFlow.packet_chain = NULL;
 	newFlow.censored_queue = NULL;
+	newFlow.upstream_queue = NULL;
+	newFlow.upstream_remaining = 0;
 	newFlow.outbox = NULL;
 	newFlow.outbox_len = 0;
 	newFlow.outbox_offset = 0;
@@ -102,6 +104,9 @@ int update_flow(flow *f) {
 
 	record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_LEN;
 	data_len = f->packet_chain->data_len;
+	if(f->packet_chain == NULL){
+		return 0;
+	}
 	packet *current = f->packet_chain;
 	int incoming = current->incoming;
 	record = calloc(1, record_len);

+ 2 - 0
server/flow.h

@@ -76,6 +76,8 @@ typedef struct flow_st {
 	int resume_session;
 	packet *packet_chain; /* currently held data */
 	queue_block *censored_queue;
+	queue_block *upstream_queue;
+	uint32_t upstream_remaining;
 	DH *dh;
 
 	uint8_t handshake_hash[EVP_MAX_MD_SIZE];

+ 98 - 7
server/relay.c

@@ -116,25 +116,112 @@ int read_header(flow *f, struct packet_info *info){
 		return 0;
 	}
 
-	struct record_header *record_hdr = (struct record_header*) p;
-	uint32_t record_length = RECORD_LEN(record_hdr);
+	uint8_t *record_ptr = NULL;
+	struct record_header *record_hdr;
+	uint32_t record_length;
+	if(f->upstream_remaining > 0){
+	//check to see whether the previous record has finished
+		if(f->upstream_remaining > info->app_data_len){
+			//ignore entire packet for now
+		printf("US: received some data but still waiting\n");
+			queue_block *new_block = calloc(1, sizeof(queue_block));
+			uint8_t *block_data = calloc(1, info->app_data_len);
+			memcpy(block_data, p, info->app_data_len);
+
+			new_block->len = info->app_data_len;
+			new_block->offset = 0;
+			new_block->data = block_data;
+			new_block->next = NULL;
+			//add block to upstream data chain
+			if(f->upstream_queue == NULL){
+				f->upstream_queue = new_block;
+			} else {
+				queue_block *last = f->upstream_queue;
+				while(last->next != NULL){
+					last = last->next;
+				}
+				last->next = new_block;
+			}
+			
+			f->upstream_remaining -= info->app_data_len;
+			return 0;
+
+
+		} else {
+			//process what we have
+		printf("US: received remainder of packet\n");
+		printf("US: %d bytes of packet unused\n", info->app_data_len - f->upstream_remaining);
+			record_hdr = (struct record_header*) f->upstream_queue->data;
+			record_length = RECORD_LEN(record_hdr);
+			record_ptr = calloc(1, record_length+ RECORD_HEADER_LEN);
+			queue_block *current = f->upstream_queue;
+			int32_t offset =0;
+			while(f->upstream_queue != NULL){
+				memcpy(record_ptr+offset, current->data, current->len);
+				offset += current->len;
+				free(current->data);
+				f->upstream_queue = current->next;
+				free(current);
+			}
+			memcpy(record_ptr+offset, p, f->upstream_remaining);
+			p = record_ptr;
+			f->upstream_remaining = 0;
+		}
+	} else {
+		//check to see if the new record is too long
+		printf("US: received beginning of packet\n");
+		record_hdr = (struct record_header*) p;
+		record_length = RECORD_LEN(record_hdr);
+		if(record_length > info->app_data_len){
+			printf("ERROR: record bigger than incoming packet\n");
+				fflush(stdout);
+
+			//add info to upstream queue
+			queue_block *new_block = calloc(1, sizeof(queue_block));
+			uint8_t *block_data = calloc(1, info->app_data_len);
+			memcpy(block_data, p, info->app_data_len);
+
+			new_block->len = info->app_data_len - RECORD_HEADER_LEN;
+			new_block->offset = record_length; //re-appropriate this for len of record
+			new_block->data = block_data;
+			new_block->next = NULL;
+
+			//add block to upstream queue
+			if(f->upstream_queue == NULL){
+				f->upstream_queue = new_block;
+			} else {
+				queue_block *last = f->upstream_queue;
+				while(last->next != NULL){
+					last = last->next;
+				}
+				last->next = new_block;
+			}
+			
+			f->upstream_remaining = record_length - new_block->len;
+			return 0;
+		}
+	}
+
 
 	printf("HERE\n");
 	fflush(stdout);
 
-	uint8_t *decrypted_data = calloc(1, info->app_data_len);
+	p+= RECORD_HEADER_LEN;
+	uint8_t *decrypted_data = calloc(1, record_length);
 
 	printf("HERE2\n");
 	fflush(stdout);
-	p+= RECORD_HEADER_LEN;
 
 	memcpy(decrypted_data, p, record_length);
 	printf("HERE3\n");
 	fflush(stdout);
 
-	if(!encrypt(f, decrypted_data, decrypted_data, record_length, 0, record_hdr->type, 0)){
+	int32_t decrypted_len = encrypt(f, decrypted_data, decrypted_data, record_length, 0, record_hdr->type, 0);
+	if(decrypted_len<0){
 		fprintf(stdout,"upstream decryption failed\n");
-	fflush(stdout);
+		fflush(stdout);
+		if(record_ptr != NULL)
+			free(record_ptr);
 		return 0;
 	} else {
 		fprintf(stdout, "upstream decryption succeeded\n");
@@ -159,6 +246,8 @@ int read_header(flow *f, struct packet_info *info){
 	uint8_t *upstream_data;
 	if(header_ptr == NULL){
 		printf("UPSTREAM: No x-slitheen header found\n");
+		if(record_ptr != NULL)
+			free(record_ptr);
 		return 0;
 	}
 	printf("UPSTREAM: Found x-slitheen header\n");
@@ -170,7 +259,7 @@ int read_header(flow *f, struct packet_info *info){
 	char *messages[50]; //TODO:make not just 10?
 	messages[0] = header_ptr;
 	char *c = header_ptr;
-	while(*c != '\r'){
+	while(*c != '\r' && *c != '\0'){
 		if(*c == ' '){
 			*c = '\0';
 			messages[num_messages] = c+1;
@@ -344,6 +433,8 @@ int read_header(flow *f, struct packet_info *info){
 		printf("failed to write all bytes to pipe\n");
 	}*/
 	free(decrypted_data);
+	if(record_ptr != NULL)
+		free(record_ptr);
 
 	return 0;