diff options
Diffstat (limited to 'toxcore/TCP_client.c')
-rw-r--r-- | toxcore/TCP_client.c | 113 |
1 files changed, 100 insertions, 13 deletions
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index dbcae11b..02d4e7dc 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c | |||
@@ -109,7 +109,7 @@ static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data | |||
109 | /* return 0 if pending data was sent completely | 109 | /* return 0 if pending data was sent completely |
110 | * return -1 if it wasn't | 110 | * return -1 if it wasn't |
111 | */ | 111 | */ |
112 | static int send_pending_data(TCP_Client_Connection *con) | 112 | static int send_pending_data_nonpriority(TCP_Client_Connection *con) |
113 | { | 113 | { |
114 | if (con->last_packet_length == 0) { | 114 | if (con->last_packet_length == 0) { |
115 | return 0; | 115 | return 0; |
@@ -127,24 +127,95 @@ static int send_pending_data(TCP_Client_Connection *con) | |||
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | if (len > left) | 130 | con->last_packet_sent += len; |
131 | return -1; | ||
132 | } | ||
133 | |||
134 | /* return 0 if pending data was sent completely | ||
135 | * return -1 if it wasn't | ||
136 | */ | ||
137 | static int send_pending_data(TCP_Client_Connection *con) | ||
138 | { | ||
139 | /* finish sending current non-priority packet */ | ||
140 | if (send_pending_data_nonpriority(con) == -1) { | ||
131 | return -1; | 141 | return -1; |
142 | } | ||
143 | |||
144 | TCP_Priority_List *p = con->priority_queue_start; | ||
145 | |||
146 | while (p) { | ||
147 | uint16_t left = p->size - p->sent; | ||
148 | int len = send(con->sock, p->data + p->sent, left, MSG_NOSIGNAL); | ||
149 | |||
150 | if (len != left) { | ||
151 | if (len > 0) { | ||
152 | p->sent += len; | ||
153 | } | ||
154 | |||
155 | break; | ||
156 | } | ||
157 | |||
158 | TCP_Priority_List *pp = p; | ||
159 | p = p->next; | ||
160 | free(pp); | ||
161 | } | ||
162 | |||
163 | con->priority_queue_start = p; | ||
164 | |||
165 | if (!p) { | ||
166 | con->priority_queue_end = NULL; | ||
167 | return 0; | ||
168 | } | ||
132 | 169 | ||
133 | con->last_packet_sent += len; | ||
134 | return -1; | 170 | return -1; |
135 | } | 171 | } |
136 | 172 | ||
173 | /* return 0 on failure (only if malloc fails) | ||
174 | * return 1 on success | ||
175 | */ | ||
176 | static _Bool add_priority(TCP_Client_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent) | ||
177 | { | ||
178 | TCP_Priority_List *p = con->priority_queue_end, *new; | ||
179 | new = malloc(sizeof(TCP_Priority_List) + size); | ||
180 | |||
181 | if (!new) { | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | new->next = NULL; | ||
186 | new->size = size; | ||
187 | new->sent = sent; | ||
188 | memcpy(new->data, packet, size); | ||
189 | |||
190 | if (p) { | ||
191 | p->next = new; | ||
192 | } else { | ||
193 | con->priority_queue_start = new; | ||
194 | } | ||
195 | |||
196 | con->priority_queue_end = new; | ||
197 | return 1; | ||
198 | } | ||
199 | |||
137 | /* return 1 on success. | 200 | /* return 1 on success. |
138 | * return 0 if could not send packet. | 201 | * return 0 if could not send packet. |
139 | * return -1 on failure (connection must be killed). | 202 | * return -1 on failure (connection must be killed). |
140 | */ | 203 | */ |
141 | static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length) | 204 | static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length, |
205 | _Bool priority) | ||
142 | { | 206 | { |
143 | if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) | 207 | if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE) |
144 | return -1; | 208 | return -1; |
145 | 209 | ||
146 | if (send_pending_data(con) == -1) | 210 | _Bool sendpriority = 1; |
147 | return 0; | 211 | |
212 | if (send_pending_data(con) == -1) { | ||
213 | if (priority) { | ||
214 | sendpriority = 0; | ||
215 | } else { | ||
216 | return 0; | ||
217 | } | ||
218 | } | ||
148 | 219 | ||
149 | uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; | 220 | uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; |
150 | 221 | ||
@@ -155,6 +226,22 @@ static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const | |||
155 | if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) | 226 | if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) |
156 | return -1; | 227 | return -1; |
157 | 228 | ||
229 | if (priority) { | ||
230 | len = sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0; | ||
231 | |||
232 | if (len <= 0) { | ||
233 | len = 0; | ||
234 | } else { | ||
235 | increment_nonce(con->sent_nonce); | ||
236 | } | ||
237 | |||
238 | if (len == sizeof(packet)) { | ||
239 | return 1; | ||
240 | } | ||
241 | |||
242 | return add_priority(con, packet, sizeof(packet), len); | ||
243 | } | ||
244 | |||
158 | len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL); | 245 | len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL); |
159 | 246 | ||
160 | if (len <= 0) | 247 | if (len <= 0) |
@@ -180,7 +267,7 @@ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key) | |||
180 | uint8_t packet[1 + crypto_box_PUBLICKEYBYTES]; | 267 | uint8_t packet[1 + crypto_box_PUBLICKEYBYTES]; |
181 | packet[0] = TCP_PACKET_ROUTING_REQUEST; | 268 | packet[0] = TCP_PACKET_ROUTING_REQUEST; |
182 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); | 269 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); |
183 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); | 270 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1); |
184 | } | 271 | } |
185 | 272 | ||
186 | void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, | 273 | void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id, |
@@ -218,7 +305,7 @@ int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, u | |||
218 | uint8_t packet[1 + length]; | 305 | uint8_t packet[1 + length]; |
219 | packet[0] = con_id + NUM_RESERVED_PORTS; | 306 | packet[0] = con_id + NUM_RESERVED_PORTS; |
220 | memcpy(packet + 1, data, length); | 307 | memcpy(packet + 1, data, length); |
221 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); | 308 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0); |
222 | } | 309 | } |
223 | 310 | ||
224 | /* return 1 on success. | 311 | /* return 1 on success. |
@@ -234,7 +321,7 @@ int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const | |||
234 | packet[0] = TCP_PACKET_OOB_SEND; | 321 | packet[0] = TCP_PACKET_OOB_SEND; |
235 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); | 322 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); |
236 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, data, length); | 323 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, data, length); |
237 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); | 324 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0); |
238 | } | 325 | } |
239 | 326 | ||
240 | 327 | ||
@@ -280,7 +367,7 @@ static int send_disconnect_notification(TCP_Client_Connection *con, uint8_t id) | |||
280 | uint8_t packet[1 + 1]; | 367 | uint8_t packet[1 + 1]; |
281 | packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION; | 368 | packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION; |
282 | packet[1] = id; | 369 | packet[1] = id; |
283 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); | 370 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1); |
284 | } | 371 | } |
285 | 372 | ||
286 | /* return 1 on success. | 373 | /* return 1 on success. |
@@ -297,7 +384,7 @@ static int send_ping_request(TCP_Client_Connection *con) | |||
297 | memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t)); | 384 | memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t)); |
298 | int ret; | 385 | int ret; |
299 | 386 | ||
300 | if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet))) == 1) { | 387 | if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) { |
301 | con->ping_request_id = 0; | 388 | con->ping_request_id = 0; |
302 | } | 389 | } |
303 | 390 | ||
@@ -318,7 +405,7 @@ static int send_ping_response(TCP_Client_Connection *con) | |||
318 | memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t)); | 405 | memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t)); |
319 | int ret; | 406 | int ret; |
320 | 407 | ||
321 | if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet))) == 1) { | 408 | if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) { |
322 | con->ping_response_id = 0; | 409 | con->ping_response_id = 0; |
323 | } | 410 | } |
324 | 411 | ||
@@ -348,7 +435,7 @@ int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t | |||
348 | uint8_t packet[1 + length]; | 435 | uint8_t packet[1 + length]; |
349 | packet[0] = TCP_PACKET_ONION_REQUEST; | 436 | packet[0] = TCP_PACKET_ONION_REQUEST; |
350 | memcpy(packet + 1, data, length); | 437 | memcpy(packet + 1, data, length); |
351 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet)); | 438 | return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0); |
352 | } | 439 | } |
353 | 440 | ||
354 | void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, | 441 | void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data, |