diff options
Diffstat (limited to 'core/Lossless_UDP.c')
-rw-r--r-- | core/Lossless_UDP.c | 427 |
1 files changed, 275 insertions, 152 deletions
diff --git a/core/Lossless_UDP.c b/core/Lossless_UDP.c index 6be8328f..4affc38f 100644 --- a/core/Lossless_UDP.c +++ b/core/Lossless_UDP.c | |||
@@ -21,67 +21,95 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* TODO: clean this file a bit. | 24 | /* |
25 | There are a couple of useless variables to get rid of. */ | 25 | * TODO: clean this file a bit. |
26 | * There are a couple of useless variables to get rid of. | ||
27 | */ | ||
28 | |||
26 | #include "Lossless_UDP.h" | 29 | #include "Lossless_UDP.h" |
27 | 30 | ||
28 | /* maximum data packets in sent and receive queues. */ | 31 | /* maximum data packets in sent and receive queues. */ |
29 | #define MAX_QUEUE_NUM 16 | 32 | #define MAX_QUEUE_NUM 16 |
30 | |||
31 | /* maximum length of the data in the data packets */ | ||
32 | /* #define MAX_DATA_SIZE 1024 */ /* defined in Lossless_UDP.h */ | ||
33 | 33 | ||
34 | /* maximum number of data packets in the buffer */ | 34 | /* maximum number of data packets in the buffer */ |
35 | #define BUFFER_PACKET_NUM (16-1) | 35 | #define BUFFER_PACKET_NUM (16-1) |
36 | 36 | ||
37 | /* Lossless UDP connection timeout. | 37 | /* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */ |
38 | timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */ | ||
39 | #define CONNEXION_TIMEOUT 5 | 38 | #define CONNEXION_TIMEOUT 5 |
40 | 39 | ||
41 | /* initial amount of sync/hanshake packets to send per second. */ | 40 | /* initial amount of sync/hanshake packets to send per second. */ |
42 | #define SYNC_RATE 2 | 41 | #define SYNC_RATE 2 |
43 | 42 | ||
44 | /* initial send rate of data. */ | 43 | /* initial send rate of data. */ |
45 | #define DATA_SYNC_RATE 30 | 44 | #define DATA_SYNC_RATE 30 |
46 | 45 | ||
47 | typedef struct { | 46 | typedef struct { |
48 | uint8_t data[MAX_DATA_SIZE]; | 47 | uint8_t data[MAX_DATA_SIZE]; |
49 | uint16_t size; | 48 | uint16_t size; |
50 | } Data; | 49 | } Data; |
51 | 50 | ||
52 | typedef struct { | 51 | typedef struct { |
53 | IP_Port ip_port; | 52 | IP_Port ip_port; |
54 | uint8_t status; /* 0 if connection is dead, 1 if attempting handshake, | 53 | |
55 | 2 if handshake is done (we start sending SYNC packets) | 54 | /* |
56 | 3 if we are sending SYNC packets and can send data | 55 | * 0 if connection is dead, 1 if attempting handshake, |
57 | 4 if the connection has timed out. */ | 56 | * 2 if handshake is done (we start sending SYNC packets) |
58 | 57 | * 3 if we are sending SYNC packets and can send data | |
59 | uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not. | 58 | * 4 if the connection has timed out. |
60 | 2 if incoming_connection() has not returned it yet, 1 if it has. */ | 59 | */ |
61 | 60 | uint8_t status; | |
62 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ | 61 | |
63 | uint16_t data_rate; /* current data packet send rate packets per second. */ | 62 | /* |
64 | uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */ | 63 | * 1 or 2 if connection was initiated by someone else, 0 if not. |
65 | uint64_t last_sent; /* time at which our last data or handshake packet was sent. */ | 64 | * 2 if incoming_connection() has not returned it yet, 1 if it has. |
66 | uint64_t last_recvSYNC; /* time at which we last received a SYNC packet from the other */ | 65 | */ |
67 | uint64_t last_recvdata; /* time at which we last received a DATA packet from the other */ | 66 | uint8_t inbound; |
68 | uint64_t killat; /* time at which to kill the connection */ | 67 | |
69 | Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ | 68 | uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */ |
70 | Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ | 69 | uint16_t data_rate; /* current data packet send rate packets per second. */ |
71 | uint32_t handshake_id1; | 70 | |
72 | uint32_t handshake_id2; | 71 | uint64_t last_SYNC; /* time our last SYNC packet was sent. */ |
73 | uint32_t recv_packetnum; /* number of data packets received (also used as handshake_id1) */ | 72 | uint64_t last_sent; /* time our last data or handshake packet was sent. */ |
74 | uint32_t orecv_packetnum; /* number of packets received by the other peer */ | 73 | uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */ |
75 | uint32_t sent_packetnum; /* number of data packets sent */ | 74 | uint64_t last_recvdata; /* time we last received a DATA packet from the other */ |
76 | uint32_t osent_packetnum; /* number of packets sent by the other peer. */ | 75 | uint64_t killat; /* time to kill the connection */ |
77 | uint32_t sendbuff_packetnum; /* number of latest packet written onto the sendbuffer */ | 76 | |
78 | uint32_t successful_sent; /* we know all packets before that number were successfully sent */ | 77 | Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */ |
79 | uint32_t successful_read; /* packet number of last packet read with the read_packet function */ | 78 | Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */ |
80 | uint32_t req_packets[BUFFER_PACKET_NUM]; /* list of currently requested packet numbers(by the other person) */ | 79 | |
81 | uint16_t num_req_paquets; /* total number of currently requested packets(by the other person) */ | 80 | uint32_t handshake_id1; |
82 | uint8_t recv_counter; | 81 | uint32_t handshake_id2; |
83 | uint8_t send_counter; | 82 | |
84 | uint8_t timeout; /* connection timeout in seconds. */ | 83 | /* number of data packets received (also used as handshake_id1) */ |
84 | uint32_t recv_packetnum; | ||
85 | |||
86 | /* number of packets received by the other peer */ | ||
87 | uint32_t orecv_packetnum; | ||
88 | |||
89 | /* number of data packets sent */ | ||
90 | uint32_t sent_packetnum; | ||
91 | |||
92 | /* number of packets sent by the other peer. */ | ||
93 | uint32_t osent_packetnum; | ||
94 | |||
95 | /* number of latest packet written onto the sendbuffer */ | ||
96 | uint32_t sendbuff_packetnum; | ||
97 | |||
98 | /* we know all packets before that number were successfully sent */ | ||
99 | uint32_t successful_sent; | ||
100 | |||
101 | /* packet number of last packet read with the read_packet function */ | ||
102 | uint32_t successful_read; | ||
103 | |||
104 | /* list of currently requested packet numbers(by the other person) */ | ||
105 | uint32_t req_packets[BUFFER_PACKET_NUM]; | ||
106 | |||
107 | /* total number of currently requested packets(by the other person) */ | ||
108 | uint16_t num_req_paquets; | ||
109 | |||
110 | uint8_t recv_counter; | ||
111 | uint8_t send_counter; | ||
112 | uint8_t timeout; /* connection timeout in seconds. */ | ||
85 | } Connection; | 113 | } Connection; |
86 | 114 | ||
87 | 115 | ||
@@ -94,26 +122,33 @@ static uint32_t connections_number; /* Number of connections in connections arra | |||
94 | 122 | ||
95 | /* Functions */ | 123 | /* Functions */ |
96 | 124 | ||
97 | /* get connection id from IP_Port | 125 | /* |
98 | return -1 if there are no connections like we are looking for | 126 | * Get connection id from IP_Port |
99 | return id if it found it */ | 127 | * Return -1 if there are no connections like we are looking for |
128 | * Return id if it found it | ||
129 | */ | ||
100 | int getconnection_id(IP_Port ip_port) | 130 | int getconnection_id(IP_Port ip_port) |
101 | { | 131 | { |
102 | uint32_t i; | 132 | uint32_t i; |
103 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 133 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
104 | if (connections[i].ip_port.ip.i == ip_port.ip.i && | 134 | if (connections[i].ip_port.ip.i == ip_port.ip.i && |
105 | connections[i].ip_port.port == ip_port.port && connections[i].status > 0) | 135 | connections[i].ip_port.port == ip_port.port && |
136 | connections[i].status > 0) | ||
106 | return i; | 137 | return i; |
107 | } | 138 | } |
139 | |||
108 | return -1; | 140 | return -1; |
109 | } | 141 | } |
110 | 142 | ||
111 | /* table of random numbers used below. */ | 143 | /* table of random numbers used below. */ |
112 | static uint32_t randtable[6][256]; | 144 | static uint32_t randtable[6][256]; |
113 | 145 | ||
114 | /* generate a handshake_id which depends on the ip_port. | 146 | /* |
115 | this function will always give one unique handshake_id per ip_port. | 147 | * Generate a handshake_id which depends on the ip_port. |
116 | TODO: make this better */ | 148 | * This function will always give one unique handshake_id per ip_port. |
149 | * | ||
150 | * TODO: make this better | ||
151 | */ | ||
117 | uint32_t handshake_id(IP_Port source) | 152 | uint32_t handshake_id(IP_Port source) |
118 | { | 153 | { |
119 | uint32_t id = 0, i; | 154 | uint32_t id = 0, i; |
@@ -124,21 +159,27 @@ uint32_t handshake_id(IP_Port source) | |||
124 | } | 159 | } |
125 | if (id == 0) /* id can't be zero */ | 160 | if (id == 0) /* id can't be zero */ |
126 | id = 1; | 161 | id = 1; |
162 | |||
127 | return id; | 163 | return id; |
128 | } | 164 | } |
129 | 165 | ||
130 | /* change the hnshake id associated with that ip_port | 166 | /* |
131 | TODO: make this better */ | 167 | * Change the hanshake id associated with that ip_port |
168 | * | ||
169 | * TODO: make this better | ||
170 | */ | ||
132 | void change_handshake(IP_Port source) | 171 | void change_handshake(IP_Port source) |
133 | { | 172 | { |
134 | uint8_t rand = random_int() % 4; | 173 | uint8_t rand = random_int() % 4; |
135 | randtable[rand][((uint8_t *)&source)[rand]] = random_int(); | 174 | randtable[rand][((uint8_t *)&source)[rand]] = random_int(); |
136 | } | 175 | } |
137 | 176 | ||
138 | /* initialize a new connection to ip_port | 177 | /* |
139 | returns an integer corresponding to the connection id. | 178 | * Initialize a new connection to ip_port |
140 | return -1 if it could not initialize the connection. | 179 | * Returns an integer corresponding to the connection idt |
141 | if there already was an existing connection to that ip_port return its number. */ | 180 | * Return -1 if it could not initialize the connectiont |
181 | * If there already was an existing connection to that ip_port return its number. | ||
182 | */ | ||
142 | int new_connection(IP_Port ip_port) | 183 | int new_connection(IP_Port ip_port) |
143 | { | 184 | { |
144 | int connect = getconnection_id(ip_port); | 185 | int connect = getconnection_id(ip_port); |
@@ -148,8 +189,10 @@ int new_connection(IP_Port ip_port) | |||
148 | if(connections_number == connections_length) { | 189 | if(connections_number == connections_length) { |
149 | Connection * temp; | 190 | Connection * temp; |
150 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); | 191 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); |
192 | |||
151 | if(temp == NULL) | 193 | if(temp == NULL) |
152 | return -1; | 194 | return -1; |
195 | |||
153 | memset(&temp[connections_length], 0, sizeof(Connection)); | 196 | memset(&temp[connections_length], 0, sizeof(Connection)); |
154 | ++connections_length; | 197 | ++connections_length; |
155 | connections = temp; | 198 | connections = temp; |
@@ -159,31 +202,37 @@ int new_connection(IP_Port ip_port) | |||
159 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 202 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
160 | if(connections[i].status == 0) { | 203 | if(connections[i].status == 0) { |
161 | memset(&connections[i], 0, sizeof(Connection)); | 204 | memset(&connections[i], 0, sizeof(Connection)); |
162 | connections[i].ip_port = ip_port; | 205 | |
163 | connections[i].status = 1; | 206 | connections[i] = (Connection) { |
164 | connections[i].inbound = 0; | 207 | .ip_port = ip_port, |
165 | connections[i].handshake_id1 = handshake_id(ip_port); | 208 | .status = 1, |
166 | connections[i].sent_packetnum = connections[i].handshake_id1; | 209 | .inbound = 0, |
167 | connections[i].sendbuff_packetnum = connections[i].handshake_id1; | 210 | .handshake_id1 = handshake_id(ip_port), |
168 | connections[i].successful_sent = connections[i].handshake_id1; | 211 | .sent_packetnum = connections[i].handshake_id1, |
169 | connections[i].SYNC_rate = SYNC_RATE; | 212 | .sendbuff_packetnum = connections[i].handshake_id1, |
170 | connections[i].data_rate = DATA_SYNC_RATE; | 213 | .successful_sent = connections[i].handshake_id1, |
171 | connections[i].last_recvSYNC = current_time(); | 214 | .SYNC_rate = SYNC_RATE, |
172 | connections[i].last_sent = current_time(); | 215 | .data_rate = DATA_SYNC_RATE, |
173 | connections[i].killat = ~0; | 216 | .last_recvSYNC = current_time(), |
174 | connections[i].send_counter = 0; | 217 | .last_sent = current_time(), |
175 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ | 218 | .killat = ~0, |
176 | connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; | 219 | .send_counter = 0, |
220 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ | ||
221 | .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT | ||
222 | }; | ||
177 | ++connections_number; | 223 | ++connections_number; |
224 | |||
178 | return i; | 225 | return i; |
179 | } | 226 | } |
180 | } | 227 | } |
181 | return -1; | 228 | return -1; |
182 | } | 229 | } |
183 | 230 | ||
184 | /* initialize a new inbound connection from ip_port | 231 | /* |
185 | returns an integer corresponding to the connection id. | 232 | * Initialize a new inbound connection from ip_port |
186 | return -1 if it could not initialize the connection. */ | 233 | * Returns an integer corresponding to the connection id. |
234 | * Return -1 if it could not initialize the connection. | ||
235 | */ | ||
187 | int new_inconnection(IP_Port ip_port) | 236 | int new_inconnection(IP_Port ip_port) |
188 | { | 237 | { |
189 | if (getconnection_id(ip_port) != -1) | 238 | if (getconnection_id(ip_port) != -1) |
@@ -192,8 +241,10 @@ int new_inconnection(IP_Port ip_port) | |||
192 | if(connections_number == connections_length) { | 241 | if(connections_number == connections_length) { |
193 | Connection * temp; | 242 | Connection * temp; |
194 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); | 243 | temp = realloc(connections, sizeof(Connection) * (connections_length + 1)); |
244 | |||
195 | if(temp == NULL) | 245 | if(temp == NULL) |
196 | return -1; | 246 | return -1; |
247 | |||
197 | memset(&temp[connections_length], 0, sizeof(Connection)); | 248 | memset(&temp[connections_length], 0, sizeof(Connection)); |
198 | ++connections_length; | 249 | ++connections_length; |
199 | connections = temp; | 250 | connections = temp; |
@@ -203,18 +254,23 @@ int new_inconnection(IP_Port ip_port) | |||
203 | for (i = 0; i < MAX_CONNECTIONS; ++i) { | 254 | for (i = 0; i < MAX_CONNECTIONS; ++i) { |
204 | if (connections[i].status == 0) { | 255 | if (connections[i].status == 0) { |
205 | memset(&connections[i], 0, sizeof(Connection)); | 256 | memset(&connections[i], 0, sizeof(Connection)); |
206 | connections[i].ip_port = ip_port; | 257 | |
207 | connections[i].status = 2; | 258 | connections[i] = (Connection){ |
208 | connections[i].inbound = 2; | 259 | .ip_port = ip_port, |
209 | connections[i].SYNC_rate = SYNC_RATE; | 260 | .status = 2, |
210 | connections[i].data_rate = DATA_SYNC_RATE; | 261 | .inbound = 2, |
211 | connections[i].last_recvSYNC = current_time(); | 262 | .SYNC_rate = SYNC_RATE, |
212 | connections[i].last_sent = current_time(); | 263 | .data_rate = DATA_SYNC_RATE, |
213 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ | 264 | .last_recvSYNC = current_time(), |
214 | connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT; | 265 | .last_sent = current_time(), |
215 | /* if this connection isn't handled within the timeout kill it. */ | 266 | .send_counter = 127, |
216 | connections[i].killat = current_time() + 1000000UL*connections[i].timeout; | 267 | |
217 | connections[i].send_counter = 127; | 268 | /* add randomness to timeout to prevent connections getting stuck in a loop. */ |
269 | .timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT, | ||
270 | |||
271 | /* if this connection isn't handled within the timeout kill it. */ | ||
272 | .killat = current_time() + 1000000UL*connections[i].timeout | ||
273 | }; | ||
218 | ++connections_number; | 274 | ++connections_number; |
219 | return i; | 275 | return i; |
220 | } | 276 | } |
@@ -222,8 +278,10 @@ int new_inconnection(IP_Port ip_port) | |||
222 | return -1; | 278 | return -1; |
223 | } | 279 | } |
224 | 280 | ||
225 | /* returns an integer corresponding to the next connection in our incoming connection list | 281 | /* |
226 | return -1 if there are no new incoming connections in the list. */ | 282 | * Returns an integer corresponding to the next connection in our incoming connection list. |
283 | * Return -1 if there are no new incoming connections in the list. | ||
284 | */ | ||
227 | int incoming_connection() | 285 | int incoming_connection() |
228 | { | 286 | { |
229 | uint32_t i; | 287 | uint32_t i; |
@@ -233,9 +291,11 @@ int incoming_connection() | |||
233 | return i; | 291 | return i; |
234 | } | 292 | } |
235 | } | 293 | } |
294 | |||
236 | return -1; | 295 | return -1; |
237 | } | 296 | } |
238 | /*Try to free some memory from the connections array.*/ | 297 | |
298 | /* Try to free some memory from the connections array. */ | ||
239 | static void free_connections() | 299 | static void free_connections() |
240 | { | 300 | { |
241 | uint32_t i; | 301 | uint32_t i; |
@@ -245,16 +305,20 @@ static void free_connections() | |||
245 | 305 | ||
246 | if(connections_length == i) | 306 | if(connections_length == i) |
247 | return; | 307 | return; |
308 | |||
248 | Connection * temp; | 309 | Connection * temp; |
249 | temp = realloc(connections, sizeof(Connection) * i); | 310 | temp = realloc(connections, sizeof(Connection) * i); |
250 | if(temp == NULL && i != 0) | 311 | if(temp == NULL && i != 0) |
251 | return; | 312 | return; |
313 | |||
252 | connections = temp; | 314 | connections = temp; |
253 | connections_length = i; | 315 | connections_length = i; |
254 | } | 316 | } |
255 | 317 | ||
256 | /* return -1 if it could not kill the connection. | 318 | /* |
257 | return 0 if killed successfully */ | 319 | * Return -1 if it could not kill the connection. |
320 | * Return 0 if killed successfully | ||
321 | */ | ||
258 | int kill_connection(int connection_id) | 322 | int kill_connection(int connection_id) |
259 | { | 323 | { |
260 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { | 324 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { |
@@ -269,9 +333,11 @@ int kill_connection(int connection_id) | |||
269 | return -1; | 333 | return -1; |
270 | } | 334 | } |
271 | 335 | ||
272 | /* kill connection in seconds seconds. | 336 | /* |
273 | return -1 if it can not kill the connection. | 337 | * Kill connection in seconds. |
274 | return 0 if it will kill it */ | 338 | * Return -1 if it can not kill the connection. |
339 | * Return 0 if it will kill it. | ||
340 | */ | ||
275 | int kill_connection_in(int connection_id, uint32_t seconds) | 341 | int kill_connection_in(int connection_id, uint32_t seconds) |
276 | { | 342 | { |
277 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { | 343 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) { |
@@ -283,12 +349,14 @@ int kill_connection_in(int connection_id, uint32_t seconds) | |||
283 | return -1; | 349 | return -1; |
284 | } | 350 | } |
285 | 351 | ||
286 | /* check if connection is connected | 352 | /* |
287 | return 0 no. | 353 | * Check if connection is connected: |
288 | return 1 if attempting handshake | 354 | * Return 0 no. |
289 | return 2 if handshake is done | 355 | * Return 1 if attempting handshake. |
290 | return 3 if fully connected | 356 | * Return 2 if handshake is done. |
291 | return 4 if timed out and waiting to be killed */ | 357 | * Return 3 if fully connected. |
358 | * Return 4 if timed out and waiting to be killed. | ||
359 | */ | ||
292 | int is_connected(int connection_id) | 360 | int is_connected(int connection_id) |
293 | { | 361 | { |
294 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) | 362 | if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) |
@@ -327,8 +395,10 @@ char id_packet(int connection_id) | |||
327 | { | 395 | { |
328 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) | 396 | if (connection_id < 0 || connection_id >= MAX_CONNECTIONS) |
329 | return -1; | 397 | return -1; |
398 | |||
330 | if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) | 399 | if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0) |
331 | return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; | 400 | return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0]; |
401 | |||
332 | return -1; | 402 | return -1; |
333 | } | 403 | } |
334 | 404 | ||
@@ -338,7 +408,7 @@ int read_packet(int connection_id, uint8_t * data) | |||
338 | { | 408 | { |
339 | if (recvqueue(connection_id) != 0) { | 409 | if (recvqueue(connection_id) != 0) { |
340 | uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; | 410 | uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM; |
341 | uint16_t size = connections[connection_id].recvbuffer[index].size; | 411 | uint16_t size = connections[connection_id].recvbuffer[index].size; |
342 | memcpy(data, connections[connection_id].recvbuffer[index].data, size); | 412 | memcpy(data, connections[connection_id].recvbuffer[index].data, size); |
343 | ++connections[connection_id].successful_read; | 413 | ++connections[connection_id].successful_read; |
344 | connections[connection_id].recvbuffer[index].size = 0; | 414 | connections[connection_id].recvbuffer[index].size = 0; |
@@ -347,14 +417,15 @@ int read_packet(int connection_id, uint8_t * data) | |||
347 | return 0; | 417 | return 0; |
348 | } | 418 | } |
349 | 419 | ||
350 | /* return 0 if data could not be put in packet queue | 420 | /* |
351 | return 1 if data was put into the queue */ | 421 | * Return 0 if data could not be put in packet queue |
422 | * Return 1 if data was put into the queue | ||
423 | */ | ||
352 | int write_packet(int connection_id, uint8_t * data, uint32_t length) | 424 | int write_packet(int connection_id, uint8_t * data, uint32_t length) |
353 | { | 425 | { |
354 | if (length > MAX_DATA_SIZE) | 426 | if (length > MAX_DATA_SIZE || length == 0) |
355 | return 0; | ||
356 | if (length == 0) | ||
357 | return 0; | 427 | return 0; |
428 | |||
358 | if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { | 429 | if (sendqueue(connection_id) < BUFFER_PACKET_NUM) { |
359 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; | 430 | uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM; |
360 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); | 431 | memcpy(connections[connection_id].sendbuffer[index].data, data, length); |
@@ -362,6 +433,7 @@ int write_packet(int connection_id, uint8_t * data, uint32_t length) | |||
362 | connections[connection_id].sendbuff_packetnum++; | 433 | connections[connection_id].sendbuff_packetnum++; |
363 | return 1; | 434 | return 1; |
364 | } | 435 | } |
436 | |||
365 | return 0; | 437 | return 0; |
366 | } | 438 | } |
367 | 439 | ||
@@ -371,8 +443,11 @@ uint32_t missing_packets(int connection_id, uint32_t * requested) | |||
371 | uint32_t number = 0; | 443 | uint32_t number = 0; |
372 | uint32_t i; | 444 | uint32_t i; |
373 | uint32_t temp; | 445 | uint32_t temp; |
374 | if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */ | 446 | |
447 | /* don't request packets if the buffer is full. */ | ||
448 | if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) | ||
375 | return 0; | 449 | return 0; |
450 | |||
376 | for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { | 451 | for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) { |
377 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { | 452 | if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) { |
378 | temp = htonl(i); | 453 | temp = htonl(i); |
@@ -380,14 +455,19 @@ uint32_t missing_packets(int connection_id, uint32_t * requested) | |||
380 | ++number; | 455 | ++number; |
381 | } | 456 | } |
382 | } | 457 | } |
458 | |||
383 | if(number == 0) | 459 | if(number == 0) |
384 | connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; | 460 | connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum; |
461 | |||
385 | return number; | 462 | return number; |
386 | } | 463 | } |
387 | 464 | ||
388 | /* Packet sending functions | 465 | /* |
389 | One per packet type. | 466 | * BEGIN Packet sending functions |
390 | see docs/Lossless_UDP.txt for more information. */ | 467 | * One per packet type. |
468 | * see docs/Lossless_UDP.txt for more information. | ||
469 | */ | ||
470 | |||
391 | int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) | 471 | int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2) |
392 | { | 472 | { |
393 | uint8_t packet[1 + 4 + 4]; | 473 | uint8_t packet[1 + 4 + 4]; |
@@ -398,21 +478,22 @@ int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_i | |||
398 | memcpy(packet + 1, &temp, 4); | 478 | memcpy(packet + 1, &temp, 4); |
399 | temp = htonl(handshake_id2); | 479 | temp = htonl(handshake_id2); |
400 | memcpy(packet + 5, &temp, 4); | 480 | memcpy(packet + 5, &temp, 4); |
481 | |||
401 | return sendpacket(ip_port, packet, sizeof(packet)); | 482 | return sendpacket(ip_port, packet, sizeof(packet)); |
402 | } | 483 | } |
403 | 484 | ||
404 | int send_SYNC(uint32_t connection_id) | 485 | int send_SYNC(uint32_t connection_id) |
405 | { | 486 | { |
406 | |||
407 | uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; | 487 | uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)]; |
408 | uint16_t index = 0; | 488 | uint16_t index = 0; |
409 | 489 | ||
410 | IP_Port ip_port = connections[connection_id].ip_port; | 490 | IP_Port ip_port = connections[connection_id].ip_port; |
411 | uint8_t counter = connections[connection_id].send_counter; | 491 | uint8_t counter = connections[connection_id].send_counter; |
412 | uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); | 492 | uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum); |
413 | uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); | 493 | uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum); |
494 | |||
414 | uint32_t requested[BUFFER_PACKET_NUM]; | 495 | uint32_t requested[BUFFER_PACKET_NUM]; |
415 | uint32_t number = missing_packets(connection_id, requested); | 496 | uint32_t number = missing_packets(connection_id, requested); |
416 | 497 | ||
417 | packet[0] = 17; | 498 | packet[0] = 17; |
418 | index += 1; | 499 | index += 1; |
@@ -462,17 +543,24 @@ int send_DATA(uint32_t connection_id) | |||
462 | return 0; | 543 | return 0; |
463 | } | 544 | } |
464 | 545 | ||
465 | /* END of packet sending functions */ | 546 | /* |
547 | * END of packet sending functions | ||
548 | * | ||
549 | * | ||
550 | * BEGIN Packet handling functions | ||
551 | * One to handle each type of packets we receive | ||
552 | */ | ||
553 | |||
466 | 554 | ||
467 | /* Packet handling functions | 555 | /* Return 0 if handled correctly, 1 if packet is bad. */ |
468 | One to handle each type of packets we receive | ||
469 | return 0 if handled correctly, 1 if packet is bad. */ | ||
470 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | 556 | int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) |
471 | { | 557 | { |
472 | if (length != (1 + 4 + 4)) | 558 | if (length != (1 + 4 + 4)) |
473 | return 1; | 559 | return 1; |
560 | |||
474 | uint32_t temp; | 561 | uint32_t temp; |
475 | uint32_t handshake_id1, handshake_id2; | 562 | uint32_t handshake_id1, handshake_id2; |
563 | |||
476 | int connection = getconnection_id(source); | 564 | int connection = getconnection_id(source); |
477 | memcpy(&temp, packet + 1, 4); | 565 | memcpy(&temp, packet + 1, 4); |
478 | handshake_id1 = ntohl(temp); | 566 | handshake_id1 = ntohl(temp); |
@@ -485,21 +573,22 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source) | |||
485 | } | 573 | } |
486 | if (is_connected(connection) != 1) | 574 | if (is_connected(connection) != 1) |
487 | return 1; | 575 | return 1; |
488 | if (handshake_id2 == connections[connection].handshake_id1) { /* if handshake_id2 is what we sent previously as handshake_id1 */ | 576 | |
577 | /* if handshake_id2 is what we sent previously as handshake_id1 */ | ||
578 | if (handshake_id2 == connections[connection].handshake_id1) { | ||
489 | connections[connection].status = 2; | 579 | connections[connection].status = 2; |
490 | /* NOTE: is this necessary? | 580 | /* NOTE: is this necessary? |
491 | connections[connection].handshake_id2 = handshake_id1; */ | 581 | connections[connection].handshake_id2 = handshake_id1; */ |
492 | connections[connection].orecv_packetnum = handshake_id2; | 582 | connections[connection].orecv_packetnum = handshake_id2; |
493 | connections[connection].osent_packetnum = handshake_id1; | 583 | connections[connection].osent_packetnum = handshake_id1; |
494 | connections[connection].recv_packetnum = handshake_id1; | 584 | connections[connection].recv_packetnum = handshake_id1; |
495 | connections[connection].successful_read = handshake_id1; | 585 | connections[connection].successful_read = handshake_id1; |
496 | } | 586 | } |
497 | return 0; | ||
498 | 587 | ||
588 | return 0; | ||
499 | } | 589 | } |
500 | 590 | ||
501 | /* returns 1 if sync packet is valid | 591 | /* returns 1 if sync packet is valid 0 if not. */ |
502 | 0 if not. */ | ||
503 | int SYNC_valid(uint32_t length) | 592 | int SYNC_valid(uint32_t length) |
504 | { | 593 | { |
505 | if (length < 4 + 4 + 2) | 594 | if (length < 4 + 4 + 2) |
@@ -510,19 +599,19 @@ int SYNC_valid(uint32_t length) | |||
510 | return 1; | 599 | return 1; |
511 | } | 600 | } |
512 | 601 | ||
513 | /* case 1: */ | 602 | /* case 1 in handle_SYNC: */ |
514 | int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) | 603 | int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum) |
515 | { | 604 | { |
516 | if (handshake_id(source) == recv_packetnum) { | 605 | if (handshake_id(source) == recv_packetnum) { |
517 | int x = new_inconnection(source); | 606 | int x = new_inconnection(source); |
518 | if (x != -1) { | 607 | if (x != -1) { |
519 | connections[x].orecv_packetnum = recv_packetnum; | 608 | connections[x].orecv_packetnum = recv_packetnum; |
520 | connections[x].sent_packetnum = recv_packetnum; | 609 | connections[x].sent_packetnum = recv_packetnum; |
521 | connections[x].sendbuff_packetnum = recv_packetnum; | 610 | connections[x].sendbuff_packetnum = recv_packetnum; |
522 | connections[x].successful_sent = recv_packetnum; | 611 | connections[x].successful_sent = recv_packetnum; |
523 | connections[x].osent_packetnum = sent_packetnum; | 612 | connections[x].osent_packetnum = sent_packetnum; |
524 | connections[x].recv_packetnum = sent_packetnum; | 613 | connections[x].recv_packetnum = sent_packetnum; |
525 | connections[x].successful_read = sent_packetnum; | 614 | connections[x].successful_read = sent_packetnum; |
526 | 615 | ||
527 | return x; | 616 | return x; |
528 | } | 617 | } |
@@ -530,7 +619,7 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu | |||
530 | return -1; | 619 | return -1; |
531 | } | 620 | } |
532 | 621 | ||
533 | /* case 2: */ | 622 | /* case 2 in handle_SYNC: */ |
534 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) | 623 | int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum) |
535 | { | 624 | { |
536 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { | 625 | if (recv_packetnum == connections[connection_id].orecv_packetnum) { |
@@ -543,7 +632,7 @@ int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui | |||
543 | } | 632 | } |
544 | return 1; | 633 | return 1; |
545 | } | 634 | } |
546 | /* case 3: */ | 635 | /* case 3 in handle_SYNC: */ |
547 | int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, | 636 | int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets, |
548 | uint16_t number) | 637 | uint16_t number) |
549 | { | 638 | { |
@@ -553,17 +642,25 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui | |||
553 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ | 642 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */ |
554 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); | 643 | uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum); |
555 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); | 644 | uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum); |
556 | if (comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) { /* packet valid */ | 645 | |
646 | /* packet valid */ | ||
647 | if (comp_1 <= BUFFER_PACKET_NUM && | ||
648 | comp_2 <= BUFFER_PACKET_NUM && | ||
649 | comp_counter < 10 && comp_counter != 0) { | ||
650 | |||
557 | connections[connection_id].orecv_packetnum = recv_packetnum; | 651 | connections[connection_id].orecv_packetnum = recv_packetnum; |
558 | connections[connection_id].osent_packetnum = sent_packetnum; | 652 | connections[connection_id].osent_packetnum = sent_packetnum; |
559 | connections[connection_id].successful_sent = recv_packetnum; | 653 | connections[connection_id].successful_sent = recv_packetnum; |
560 | connections[connection_id].last_recvSYNC = current_time(); | 654 | connections[connection_id].last_recvSYNC = current_time(); |
561 | connections[connection_id].recv_counter = counter; | 655 | connections[connection_id].recv_counter = counter; |
656 | |||
562 | ++connections[connection_id].send_counter; | 657 | ++connections[connection_id].send_counter; |
658 | |||
563 | for (i = 0; i < number; ++i) { | 659 | for (i = 0; i < number; ++i) { |
564 | temp = ntohl(req_packets[i]); | 660 | temp = ntohl(req_packets[i]); |
565 | memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); | 661 | memcpy(connections[connection_id].req_packets + i, &temp, 4 * number); |
566 | } | 662 | } |
663 | |||
567 | connections[connection_id].num_req_paquets = number; | 664 | connections[connection_id].num_req_paquets = number; |
568 | return 0; | 665 | return 0; |
569 | } | 666 | } |
@@ -575,6 +672,7 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source) | |||
575 | 672 | ||
576 | if (!SYNC_valid(length)) | 673 | if (!SYNC_valid(length)) |
577 | return 1; | 674 | return 1; |
675 | |||
578 | int connection = getconnection_id(source); | 676 | int connection = getconnection_id(source); |
579 | uint8_t counter; | 677 | uint8_t counter; |
580 | uint32_t temp; | 678 | uint32_t temp; |
@@ -587,19 +685,27 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source) | |||
587 | recv_packetnum = ntohl(temp); | 685 | recv_packetnum = ntohl(temp); |
588 | memcpy(&temp,packet + 6, 4); | 686 | memcpy(&temp,packet + 6, 4); |
589 | sent_packetnum = ntohl(temp); | 687 | sent_packetnum = ntohl(temp); |
688 | |||
590 | if (number != 0) | 689 | if (number != 0) |
591 | memcpy(req_packets, packet + 10, 4 * number); | 690 | memcpy(req_packets, packet + 10, 4 * number); |
691 | |||
592 | if (connection == -1) | 692 | if (connection == -1) |
593 | return handle_SYNC1(source, recv_packetnum, sent_packetnum); | 693 | return handle_SYNC1(source, recv_packetnum, sent_packetnum); |
694 | |||
594 | if (connections[connection].status == 2) | 695 | if (connections[connection].status == 2) |
595 | return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum); | 696 | return handle_SYNC2(connection, counter, |
697 | recv_packetnum, sent_packetnum); | ||
698 | |||
596 | if (connections[connection].status == 3) | 699 | if (connections[connection].status == 3) |
597 | return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number); | 700 | return handle_SYNC3(connection, counter, recv_packetnum, |
701 | sent_packetnum, req_packets, number); | ||
598 | return 0; | 702 | return 0; |
599 | } | 703 | } |
600 | 704 | ||
601 | /* add a packet to the received buffer and set the recv_packetnum of the connection to its proper value. | 705 | /* |
602 | return 1 if data was too big, 0 if not. */ | 706 | * Add a packet to the received buffer and set the recv_packetnum of the |
707 | * connection to its proper value. Return 1 if data was too big, 0 if not. | ||
708 | */ | ||
603 | int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | 709 | int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) |
604 | { | 710 | { |
605 | if (size > MAX_DATA_SIZE) | 711 | if (size > MAX_DATA_SIZE) |
@@ -608,16 +714,22 @@ int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size) | |||
608 | uint32_t i; | 714 | uint32_t i; |
609 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; | 715 | uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM; |
610 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; | 716 | uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum; |
717 | |||
611 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 718 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
612 | if (i == data_num) { | 719 | if (i == data_num) { |
613 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); | 720 | memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size); |
721 | |||
614 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; | 722 | connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size; |
615 | connections[connection_id].last_recvdata = current_time(); | 723 | connections[connection_id].last_recvdata = current_time(); |
616 | if (sent_packet < BUFFER_PACKET_NUM) | 724 | |
725 | if (sent_packet < BUFFER_PACKET_NUM) { | ||
617 | connections[connection_id].osent_packetnum = data_num; | 726 | connections[connection_id].osent_packetnum = data_num; |
727 | } | ||
728 | |||
618 | break; | 729 | break; |
619 | } | 730 | } |
620 | } | 731 | } |
732 | |||
621 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { | 733 | for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) { |
622 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) | 734 | if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0) |
623 | connections[connection_id].recv_packetnum = i; | 735 | connections[connection_id].recv_packetnum = i; |
@@ -635,25 +747,30 @@ int handle_data(uint8_t *packet, uint32_t length, IP_Port source) | |||
635 | if (connection == -1) | 747 | if (connection == -1) |
636 | return 1; | 748 | return 1; |
637 | 749 | ||
638 | if (connections[connection].status != 3) /* Drop the data packet if connection is not connected. */ | 750 | /* Drop the data packet if connection is not connected. */ |
751 | if (connections[connection].status != 3) | ||
639 | return 1; | 752 | return 1; |
640 | 753 | ||
641 | if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) | 754 | if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1) |
642 | return 1; | 755 | return 1; |
756 | |||
643 | uint32_t temp; | 757 | uint32_t temp; |
644 | uint32_t number; | 758 | uint32_t number; |
645 | uint16_t size = length - 1 - 4; | 759 | uint16_t size = length - 1 - 4; |
646 | 760 | ||
647 | memcpy(&temp, packet + 1, 4); | 761 | memcpy(&temp, packet + 1, 4); |
648 | number = ntohl(temp); | 762 | number = ntohl(temp); |
763 | |||
649 | return add_recv(connection, number, packet + 5, size); | 764 | return add_recv(connection, number, packet + 5, size); |
650 | } | 765 | } |
651 | 766 | ||
652 | /* END of packet handling functions */ | 767 | /* |
768 | * END of packet handling functions | ||
769 | */ | ||
653 | 770 | ||
654 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) | 771 | int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) |
655 | { | 772 | { |
656 | switch (packet[0]) { //TODO: check if no break statement is correct??? | 773 | switch (packet[0]) { |
657 | case 16: | 774 | case 16: |
658 | return handle_handshake(packet, length, source); | 775 | return handle_handshake(packet, length, source); |
659 | 776 | ||
@@ -670,8 +787,10 @@ int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source) | |||
670 | return 0; | 787 | return 0; |
671 | } | 788 | } |
672 | 789 | ||
673 | /* Send handshake requests | 790 | /* |
674 | handshake packets are sent at the same rate as SYNC packets */ | 791 | * Send handshake requests |
792 | * handshake packets are sent at the same rate as SYNC packets | ||
793 | */ | ||
675 | void doNew() | 794 | void doNew() |
676 | { | 795 | { |
677 | uint32_t i; | 796 | uint32_t i; |
@@ -684,10 +803,13 @@ void doNew() | |||
684 | } | 803 | } |
685 | 804 | ||
686 | /* kill all timed out connections */ | 805 | /* kill all timed out connections */ |
687 | if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && | 806 | if (connections[i].status > 0 && |
688 | connections[i].status != 4) | 807 | (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time && |
689 | /* kill_connection(i); */ | 808 | connections[i].status != 4) { |
690 | connections[i].status = 4; | 809 | connections[i].status = 4; |
810 | /* kill_connection(i); */ | ||
811 | } | ||
812 | |||
691 | if (connections[i].status > 0 && connections[i].killat < temp_time) | 813 | if (connections[i].status > 0 && connections[i].killat < temp_time) |
692 | kill_connection(i); | 814 | kill_connection(i); |
693 | } | 815 | } |
@@ -720,11 +842,13 @@ void doData() | |||
720 | } | 842 | } |
721 | } | 843 | } |
722 | 844 | ||
723 | /* TODO: flow control. | ||
724 | automatically adjusts send rates of packets for optimal transmission. */ | ||
725 | |||
726 | #define MAX_SYNC_RATE 10 | 845 | #define MAX_SYNC_RATE 10 |
727 | 846 | ||
847 | /* | ||
848 | * Automatically adjusts send rates of packets for optimal transmission. | ||
849 | * | ||
850 | * TODO: flow control. | ||
851 | */ | ||
728 | void adjustRates() | 852 | void adjustRates() |
729 | { | 853 | { |
730 | uint32_t i; | 854 | uint32_t i; |
@@ -744,8 +868,7 @@ void adjustRates() | |||
744 | } | 868 | } |
745 | } | 869 | } |
746 | 870 | ||
747 | /* Call this function a couple times per second | 871 | /* Call this function a couple times per second It's the main loop. */ |
748 | It's the main loop. */ | ||
749 | void doLossless_UDP() | 872 | void doLossless_UDP() |
750 | { | 873 | { |
751 | doNew(); | 874 | doNew(); |