diff options
-rw-r--r-- | README.md | 9 | ||||
-rw-r--r-- | core/Lossless_UDP.c | 21 | ||||
-rw-r--r-- | testing/DHT_sendfiletest.c | 178 | ||||
-rw-r--r-- | testing/Lossless_UDP_testserver.c | 1 |
4 files changed, 196 insertions, 13 deletions
@@ -25,11 +25,10 @@ Your client stores the id of the peers along with their public keys used to init | |||
25 | ## Roadmap: | 25 | ## Roadmap: |
26 | 26 | ||
27 | 1. Get our DHT working perfectly.(Done, needs large scale testing though.) | 27 | 1. Get our DHT working perfectly.(Done, needs large scale testing though.) |
28 | 2. Reliable connection (See Lossless_UDP protocol) to other peers according to client id. | 28 | 2. Reliable connection (See Lossless_UDP protocol) to other peers according to client id. (Done, see DHT_sendfiletest.c for an example) |
29 | 3. Encrypted message sending with RSA (NOTE: We have not decided on the encryption yet. This was just a quick guess.) | 29 | 3. Encryption. (this is where we are now) |
30 | 4. Encrypted message sending with AES (encryption done) | 30 | 4. Optimize for streaming media. |
31 | 5. Reliable encrypted sending of data larger than the maximum packet size. | 31 | 5. |
32 | ... | ||
33 | 32 | ||
34 | ## TODO: | 33 | ## TODO: |
35 | 34 | ||
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index b92e6806..482d88b1 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -28,22 +28,22 @@ | |||
28 | 28 | ||
29 | 29 | ||
30 | //maximum data packets in sent and recieve queues. | 30 | //maximum data packets in sent and recieve queues. |
31 | #define MAX_QUEUE_NUM 32 | 31 | #define MAX_QUEUE_NUM 16 |
32 | 32 | ||
33 | //maximum length of the data in the data packets | 33 | //maximum length of the data in the data packets |
34 | #define MAX_DATA_SIZE 1024 | 34 | #define MAX_DATA_SIZE 1024 |
35 | 35 | ||
36 | //maximum number of data packets in the buffer | 36 | //maximum number of data packets in the buffer |
37 | #define BUFFER_PACKET_NUM MAX_QUEUE_NUM | 37 | #define BUFFER_PACKET_NUM (16-1) |
38 | 38 | ||
39 | //Lossless UDP connection timeout. | 39 | //Lossless UDP connection timeout. |
40 | #define CONNEXION_TIMEOUT 10 | 40 | #define CONNEXION_TIMEOUT 10 |
41 | 41 | ||
42 | //initial amount of sync/hanshake packets to send per second. | 42 | //initial amount of sync/hanshake packets to send per second. |
43 | #define SYNC_RATE 5 | 43 | #define SYNC_RATE 50 |
44 | 44 | ||
45 | //initial send rate of sync packets when data is being sent/recieved. | 45 | //initial send rate of sync packets when data is being sent/recieved. |
46 | #define DATA_SYNC_RATE 20 | 46 | #define DATA_SYNC_RATE 200 |
47 | 47 | ||
48 | typedef struct | 48 | typedef struct |
49 | { | 49 | { |
@@ -242,7 +242,7 @@ int is_connected(int connection_id) | |||
242 | //returns the ip_port of the corresponding connection. | 242 | //returns the ip_port of the corresponding connection. |
243 | IP_Port connection_ip(int connection_id) | 243 | IP_Port connection_ip(int connection_id) |
244 | { | 244 | { |
245 | if(connection_id > 0 && connection_id < MAX_CONNECTIONS) | 245 | if(connection_id >= 0 && connection_id < MAX_CONNECTIONS) |
246 | { | 246 | { |
247 | return connections[connection_id].ip_port; | 247 | return connections[connection_id].ip_port; |
248 | } | 248 | } |
@@ -290,7 +290,7 @@ int write_packet(int connection_id, char * data, uint32_t length) | |||
290 | { | 290 | { |
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | if(sendqueue(connection_id) < MAX_QUEUE_NUM) | 293 | if(sendqueue(connection_id) < BUFFER_PACKET_NUM) |
294 | { | 294 | { |
295 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; | 295 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; |
296 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); | 296 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); |
@@ -309,6 +309,11 @@ uint32_t missing_packets(int connection_id, uint32_t * requested) | |||
309 | { | 309 | { |
310 | uint32_t number = 0; | 310 | uint32_t number = 0; |
311 | uint32_t i; | 311 | uint32_t i; |
312 | |||
313 | if(recvqueue(connection_id) >= BUFFER_PACKET_NUM)//don't request packets if the buffer is full. | ||
314 | { | ||
315 | return 0; | ||
316 | } | ||
312 | for(i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++ ) | 317 | for(i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++ ) |
313 | { | 318 | { |
314 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) | 319 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) |
@@ -500,9 +505,11 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui | |||
500 | uint16_t number) | 505 | uint16_t number) |
501 | { | 506 | { |
502 | uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); | 507 | uint8_t comp_counter = (counter - connections[connection_id].recv_counter ); |
508 | //uint32_t comp_1 = (recv_packetnum - connections[connection_id].successful_sent); | ||
509 | //uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); | ||
503 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); | 510 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); |
504 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); | 511 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); |
505 | if(comp_1 < BUFFER_PACKET_NUM && comp_2 < BUFFER_PACKET_NUM && comp_counter < 10) //packet valid | 512 | if(comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) //packet valid |
506 | { | 513 | { |
507 | connections[connection_id].orecv_packetnum = recv_packetnum; | 514 | connections[connection_id].orecv_packetnum = recv_packetnum; |
508 | connections[connection_id].osent_packetnum = sent_packetnum; | 515 | connections[connection_id].osent_packetnum = sent_packetnum; |
diff --git a/testing/DHT_sendfiletest.c b/testing/DHT_sendfiletest.c new file mode 100644 index 00000000..fd4fd29f --- /dev/null +++ b/testing/DHT_sendfiletest.c | |||
@@ -0,0 +1,178 @@ | |||
1 | /* DHT sendfiletest | ||
2 | * | ||
3 | * Sends the data from a file to another client. | ||
4 | * Receives the file data that that client sends us. | ||
5 | * | ||
6 | * NOTE: this program simulates 33% packet loss. | ||
7 | * | ||
8 | * Compile with: gcc -O2 -Wall -o test ../core/DHT.c ../core/network.c ../core/Lossless_UDP.c DHT_sendfiletest.c | ||
9 | * | ||
10 | * Command line arguments are the ip and port of a node (for bootstrapping), the | ||
11 | * client_id (32 bytes) of the friend you want to send the data in filename to and | ||
12 | * the client_id this node will take. | ||
13 | * | ||
14 | * Saves all received data to: received.txt | ||
15 | * | ||
16 | * EX: ./test 127.0.0.1 33445 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef filename.txt ABCDEFGHIJKLMNOPQRSTUVWXYZabcdeg | ||
17 | */ | ||
18 | #include "../core/network.h" | ||
19 | #include "../core/DHT.h" | ||
20 | #include "../core/Lossless_UDP.h" | ||
21 | |||
22 | #include <string.h> | ||
23 | |||
24 | //Sleep function (x = milliseconds) | ||
25 | #ifdef WIN32 | ||
26 | |||
27 | #define c_sleep(x) Sleep(1*x) | ||
28 | |||
29 | #else | ||
30 | #include <unistd.h> | ||
31 | #include <arpa/inet.h> | ||
32 | #define c_sleep(x) usleep(1000*x) | ||
33 | |||
34 | #endif | ||
35 | |||
36 | #define PORT 33445 | ||
37 | |||
38 | void printip(IP_Port ip_port) | ||
39 | { | ||
40 | printf("\nIP: %u.%u.%u.%u Port: %u\n",ip_port.ip.c[0],ip_port.ip.c[1],ip_port.ip.c[2],ip_port.ip.c[3],ntohs(ip_port.port)); | ||
41 | } | ||
42 | |||
43 | int main(int argc, char *argv[]) | ||
44 | { | ||
45 | //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); | ||
46 | |||
47 | if (argc < 6) { | ||
48 | printf("usage %s ip port client_id(of friend to find ip_port of) filename(of file to send) client_id(ours)\n", argv[0]); | ||
49 | exit(0); | ||
50 | } | ||
51 | addfriend(argv[3]); | ||
52 | IP_Port friend_ip; | ||
53 | int connection = -1; | ||
54 | int inconnection = -1; | ||
55 | |||
56 | //initialize networking | ||
57 | //bind to ip 0.0.0.0:PORT | ||
58 | IP ip; | ||
59 | ip.i = 0; | ||
60 | init_networking(ip, PORT); | ||
61 | |||
62 | memcpy(self_client_id, argv[5], 32); | ||
63 | |||
64 | |||
65 | perror("Initialization"); | ||
66 | IP_Port bootstrap_ip_port; | ||
67 | bootstrap_ip_port.port = htons(atoi(argv[2])); | ||
68 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); | ||
69 | bootstrap(bootstrap_ip_port); | ||
70 | |||
71 | IP_Port ip_port; | ||
72 | char data[MAX_UDP_PACKET_SIZE]; | ||
73 | uint32_t length; | ||
74 | |||
75 | char buffer1[128]; | ||
76 | int read1 = 0; | ||
77 | char buffer2[128]; | ||
78 | int read2 = 0; | ||
79 | FILE *file1 = fopen(argv[4], "rb"); | ||
80 | if ( file1==NULL ){printf("Error opening file.\n");return 1;} | ||
81 | FILE *file2 = fopen("received.txt", "wb"); | ||
82 | if ( file2==NULL ){return 1;} | ||
83 | read1 = fread(buffer1, 1, 128, file1); | ||
84 | |||
85 | while(1) | ||
86 | { | ||
87 | |||
88 | while(recievepacket(&ip_port, data, &length) != -1) | ||
89 | { | ||
90 | if(rand() % 3 != 1)//simulate packet loss | ||
91 | { | ||
92 | if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) | ||
93 | { | ||
94 | //if packet is not recognized | ||
95 | printf("Received unhandled packet with length: %u\n", length); | ||
96 | } | ||
97 | else | ||
98 | { | ||
99 | printf("Received handled packet with length: %u\n", length); | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | friend_ip = getfriendip(argv[3]); | ||
104 | if(friend_ip.ip.i != 0) | ||
105 | { | ||
106 | if(connection == -1) | ||
107 | { | ||
108 | printf("Started connecting to friend:"); | ||
109 | printip(friend_ip); | ||
110 | connection = new_connection(friend_ip); | ||
111 | } | ||
112 | } | ||
113 | if(inconnection == -1) | ||
114 | { | ||
115 | inconnection = incoming_connection(); | ||
116 | if(inconnection != -1) | ||
117 | { | ||
118 | printf("Someone connected to us:"); | ||
119 | printip(connection_ip(inconnection)); | ||
120 | } | ||
121 | } | ||
122 | //if someone connected to us write what he sends to a file | ||
123 | //also send him our file. | ||
124 | if(inconnection != -1) | ||
125 | { | ||
126 | if(write_packet(inconnection, buffer1, read1)) | ||
127 | { | ||
128 | printf("Wrote data.\n"); | ||
129 | read1 = fread(buffer1, 1, 128, file1); | ||
130 | } | ||
131 | read2 = read_packet(inconnection, buffer2); | ||
132 | if(read2 != 0) | ||
133 | { | ||
134 | printf("Received data.\n"); | ||
135 | if(!fwrite(buffer2, read2, 1, file2)) | ||
136 | { | ||
137 | printf("file write error\n"); | ||
138 | } | ||
139 | if(read2 < 128) | ||
140 | { | ||
141 | fclose(file2); | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | //if we are connected to a friend send him data from the file. | ||
146 | //also put what he sends us in a file. | ||
147 | if(is_connected(connection) == 3) | ||
148 | { | ||
149 | if(write_packet(0, buffer1, read1)) | ||
150 | { | ||
151 | printf("Wrote data.\n"); | ||
152 | read1 = fread(buffer1, 1, 128, file1); | ||
153 | } | ||
154 | read2 = read_packet(0, buffer2); | ||
155 | if(read2 != 0) | ||
156 | { | ||
157 | printf("Received data.\n"); | ||
158 | if(!fwrite(buffer2, read2, 1, file2)) | ||
159 | { | ||
160 | printf("file write error\n"); | ||
161 | } | ||
162 | if(read2 < 128) | ||
163 | { | ||
164 | fclose(file2); | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | doDHT(); | ||
169 | doLossless_UDP(); | ||
170 | //print_clientlist(); | ||
171 | //print_friendlist(); | ||
172 | //c_sleep(300); | ||
173 | c_sleep(1); | ||
174 | } | ||
175 | |||
176 | shutdown_networking(); | ||
177 | return 0; | ||
178 | } \ No newline at end of file | ||
diff --git a/testing/Lossless_UDP_testserver.c b/testing/Lossless_UDP_testserver.c index 00e537ac..8357c2ef 100644 --- a/testing/Lossless_UDP_testserver.c +++ b/testing/Lossless_UDP_testserver.c | |||
@@ -174,7 +174,6 @@ int main(int argc, char *argv[]) | |||
174 | if(is_connected(connection) >= 2) | 174 | if(is_connected(connection) >= 2) |
175 | { | 175 | { |
176 | read = read_packet(connection, buffer); | 176 | read = read_packet(connection, buffer); |
177 | |||
178 | if(read != 0) | 177 | if(read != 0) |
179 | { | 178 | { |
180 | // printf("Recieved data.\n"); | 179 | // printf("Recieved data.\n"); |