Changes in uspace/srv/net/tl/tcp/tcp.c [472020fc:89e57cee] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/tcp.c
r472020fc r89e57cee 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * TCP module implementation. 35 * @see tcp.h 36 36 */ 37 38 #include "tcp.h" 39 #include "tcp_header.h" 40 #include "tcp_module.h" 37 41 38 42 #include <assert.h> … … 72 76 #include <tl_interface.h> 73 77 74 #include "tcp.h"75 #include "tcp_header.h"76 #include "tcp_module.h"77 78 78 /** TCP module name. */ 79 79 #define NAME "TCP protocol" … … 110 110 111 111 /** Returns a value indicating whether the value is in the interval respecting 112 * 112 * the possible overflow. 113 113 * 114 * The high end and/or the value may overflow, be lower than the low value. 115 * @param[in] lower The last value before the interval. 116 * @param[in] value The value to be checked. 117 * @param[in] higher_equal The last value in the interval. 114 * The high end and/or the value may overflow, be lower than the low value. 115 * 116 * @param[in] lower The last value before the interval. 117 * @param[in] value The value to be checked. 118 * @param[in] higher_equal The last value in the interval. 118 119 */ 119 120 #define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \ … … 165 166 }; 166 167 167 /** Releases the packet and returns the result. 168 * @param[in] packet The packet queue to be released. 169 * @param[in] result The result to be returned. 170 * @return The result parameter. 171 */ 172 int tcp_release_and_return(packet_t packet, int result); 173 174 void tcp_prepare_operation_header(socket_core_ref socket, 175 tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, 176 int finalize); 177 int tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t), 178 socket_core_ref socket, tcp_socket_data_ref socket_data, 179 size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, 180 int globals_read_only); 181 void tcp_free_socket_data(socket_core_ref socket); 182 183 int tcp_timeout(void *data); 184 185 int tcp_release_after_timeout(void *data); 186 187 int tcp_process_packet(device_id_t device_id, packet_t packet, 188 services_t error); 189 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, 190 struct sockaddr *addr, socklen_t addrlen); 191 int tcp_queue_prepare_packet(socket_core_ref socket, 192 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length); 193 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, 194 packet_t packet, size_t data_length); 195 packet_t tcp_get_packets_to_send(socket_core_ref socket, 196 tcp_socket_data_ref socket_data); 197 void tcp_send_packets(device_id_t device_id, packet_t packet); 198 199 void tcp_process_acknowledgement(socket_core_ref socket, 200 tcp_socket_data_ref socket_data, tcp_header_ref header); 201 packet_t tcp_send_prepare_packet(socket_core_ref socket, 202 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, 203 size_t sequence_number); 204 packet_t tcp_prepare_copy(socket_core_ref socket, 205 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, 206 size_t sequence_number); 207 void tcp_retransmit_packet(socket_core_ref socket, 208 tcp_socket_data_ref socket_data, size_t sequence_number); 209 int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, 210 tcp_socket_data_ref socket_data, int synchronize, int finalize); 211 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data); 212 213 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data); 214 215 int tcp_process_listen(socket_core_ref listening_socket, 216 tcp_socket_data_ref listening_socket_data, tcp_header_ref header, 217 packet_t packet, struct sockaddr *src, struct sockaddr *dest, 218 size_t addrlen); 219 int tcp_process_syn_sent(socket_core_ref socket, 220 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 221 int tcp_process_syn_received(socket_core_ref socket, 222 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 223 int tcp_process_established(socket_core_ref socket, 224 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, 225 int fragments, size_t total_length); 226 int tcp_queue_received_packet(socket_core_ref socket, 227 tcp_socket_data_ref socket_data, packet_t packet, int fragments, 228 size_t total_length); 229 230 int tcp_received_msg(device_id_t device_id, packet_t packet, 231 services_t receiver, services_t error); 232 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 233 234 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, 235 int backlog); 236 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, 237 struct sockaddr *addr, socklen_t addrlen); 238 int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, 239 int flags, size_t * addrlen); 240 int tcp_send_message(socket_cores_ref local_sockets, int socket_id, 241 int fragments, size_t * data_fragment_size, int flags); 242 int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, 243 int new_socket_id, size_t * data_fragment_size, size_t * addrlen); 244 int tcp_close_message(socket_cores_ref local_sockets, int socket_id); 168 static int tcp_release_and_return(packet_t, int); 169 static void tcp_prepare_operation_header(socket_core_ref, tcp_socket_data_ref, 170 tcp_header_ref, int synchronize, int); 171 static int tcp_prepare_timeout(int (*)(void *), socket_core_ref, 172 tcp_socket_data_ref, size_t, tcp_socket_state_t, suseconds_t, int); 173 static void tcp_free_socket_data(socket_core_ref); 174 175 static int tcp_timeout(void *); 176 177 static int tcp_release_after_timeout(void *); 178 179 static int tcp_process_packet(device_id_t, packet_t, services_t); 180 static int tcp_connect_core(socket_core_ref, socket_cores_ref, 181 struct sockaddr *, socklen_t); 182 static int tcp_queue_prepare_packet(socket_core_ref, tcp_socket_data_ref, 183 packet_t, size_t); 184 static int tcp_queue_packet(socket_core_ref, tcp_socket_data_ref, packet_t, 185 size_t); 186 static packet_t tcp_get_packets_to_send(socket_core_ref, tcp_socket_data_ref); 187 static void tcp_send_packets(device_id_t, packet_t); 188 189 static void tcp_process_acknowledgement(socket_core_ref, tcp_socket_data_ref, 190 tcp_header_ref); 191 static packet_t tcp_send_prepare_packet(socket_core_ref, tcp_socket_data_ref, 192 packet_t, size_t, size_t); 193 static packet_t tcp_prepare_copy(socket_core_ref, tcp_socket_data_ref, packet_t, 194 size_t, size_t); 195 /* static */ void tcp_retransmit_packet(socket_core_ref, tcp_socket_data_ref, 196 size_t); 197 static int tcp_create_notification_packet(packet_t *, socket_core_ref, 198 tcp_socket_data_ref, int, int); 199 static void tcp_refresh_socket_data(tcp_socket_data_ref); 200 201 static void tcp_initialize_socket_data(tcp_socket_data_ref); 202 203 static int tcp_process_listen(socket_core_ref, tcp_socket_data_ref, 204 tcp_header_ref, packet_t, struct sockaddr *, struct sockaddr *, size_t); 205 static int tcp_process_syn_sent(socket_core_ref, tcp_socket_data_ref, 206 tcp_header_ref, packet_t); 207 static int tcp_process_syn_received(socket_core_ref, tcp_socket_data_ref, 208 tcp_header_ref, packet_t); 209 static int tcp_process_established(socket_core_ref, tcp_socket_data_ref, 210 tcp_header_ref, packet_t, int, size_t); 211 static int tcp_queue_received_packet(socket_core_ref, tcp_socket_data_ref, 212 packet_t, int, size_t); 213 214 static int tcp_received_msg(device_id_t, packet_t, services_t, services_t); 215 static int tcp_process_client_messages(ipc_callid_t, ipc_call_t); 216 217 static int tcp_listen_message(socket_cores_ref, int, int); 218 static int tcp_connect_message(socket_cores_ref, int, struct sockaddr *, 219 socklen_t); 220 static int tcp_recvfrom_message(socket_cores_ref, int, int, size_t *); 221 static int tcp_send_message(socket_cores_ref, int, int, size_t *, int); 222 static int tcp_accept_message(socket_cores_ref, int, int, size_t *, size_t *); 223 static int tcp_close_message(socket_cores_ref, int); 245 224 246 225 /** TCP global data. */ 247 226 tcp_globals_t tcp_globals; 248 227 228 /** Initializes the TCP module. 229 * 230 * @param[in] client_connection The client connection processing function. The 231 * module skeleton propagates its own one. 232 * @returns EOK on success. 233 * @returns ENOMEM if there is not enough memory left. 234 */ 249 235 int tcp_initialize(async_client_conn_t client_connection) 250 236 { … … 314 300 size_t addrlen; 315 301 316 if (error) { 317 switch (error) { 318 case SERVICE_ICMP: 319 // process error 320 result = icmp_client_process_packet(packet, &type, 321 &code, NULL, NULL); 322 if (result < 0) 323 return tcp_release_and_return(packet, result); 324 325 length = (size_t) result; 326 if (ERROR_OCCURRED(packet_trim(packet, length, 0))) { 327 return tcp_release_and_return(packet, 328 ERROR_CODE); 329 } 330 break; 331 332 default: 333 return tcp_release_and_return(packet, ENOTSUP); 334 } 302 switch (error) { 303 case SERVICE_NONE: 304 break; 305 case SERVICE_ICMP: 306 // process error 307 result = icmp_client_process_packet(packet, &type, &code, NULL, 308 NULL); 309 if (result < 0) 310 return tcp_release_and_return(packet, result); 311 312 length = (size_t) result; 313 if (ERROR_OCCURRED(packet_trim(packet, length, 0))) 314 return tcp_release_and_return(packet, ERROR_CODE); 315 break; 316 default: 317 return tcp_release_and_return(packet, ENOTSUP); 335 318 } 336 319 … … 379 362 ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 380 363 0); 381 if (!socket) {382 if (tl_prepare_icmp_packet(tcp_globals.net_phone,383 tcp_globals.icmp_phone, packet, error) == EOK) {384 icmp_destination_unreachable_msg(385 tcp_globals.icmp_phone, ICMP_PORT_UNREACH,386 387 388 389 390 } 364 } 365 if (!socket) { 366 if (tl_prepare_icmp_packet(tcp_globals.net_phone, 367 tcp_globals.icmp_phone, packet, error) == EOK) { 368 icmp_destination_unreachable_msg(tcp_globals.icmp_phone, 369 ICMP_PORT_UNREACH, 0, packet); 370 } 371 return EADDRNOTAVAIL; 372 } 373 391 374 printf("socket id %d\n", socket->socket_id); 392 375 socket_data = (tcp_socket_data_ref) socket->specific_data; … … 402 385 total_length = 0; 403 386 do { 404 ++fragments;387 fragments++; 405 388 length = packet_get_data_length(next_packet); 406 389 if (length <= 0) … … 421 404 422 405 if (error) 423 goto error;406 goto has_error_service; 424 407 425 408 if (socket_data->state == TCP_SOCKET_LISTEN) { 426 427 409 if (socket_data->pseudo_header) { 428 410 free(socket_data->pseudo_header); … … 464 446 } 465 447 466 error:448 has_error_service: 467 449 fibril_rwlock_read_unlock(&tcp_globals.lock); 468 450 … … 507 489 int 508 490 tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, 509 tcp_header_ref header, packet_t packet, int fragments, 510 size_t total_length) 491 tcp_header_ref header, packet_t packet, int fragments, size_t total_length) 511 492 { 512 493 ERROR_DECLARE; … … 684 665 continue; 685 666 // at least partly following data? 686 } else if (IS_IN_INTERVAL_OVERFLOW(687 sequence_number, socket_data->next_incoming,688 new_sequence_number)) {667 } 668 if (IS_IN_INTERVAL_OVERFLOW(sequence_number, 669 socket_data->next_incoming, new_sequence_number)) { 689 670 if (socket_data->next_incoming < 690 671 new_sequence_number) { … … 961 942 listening_socket = socket_port_find(&tcp_globals.sockets, 962 943 listening_port, SOCKET_MAP_KEY_LISTENING, 0); 963 if ( (!listening_socket)||944 if (!listening_socket || 964 945 (listening_socket->socket_id != listening_socket_id)) { 965 946 fibril_rwlock_write_unlock(&tcp_globals.lock); … … 1191 1172 if (number == socket_data->expected) { 1192 1173 // increase the counter 1193 ++socket_data->expected_count;1174 socket_data->expected_count++; 1194 1175 if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) { 1195 1176 socket_data->expected_count = 1; … … 1200 1181 } 1201 1182 1202 int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, 1203 ipc_call_t * answer, int *answer_count) 1183 /** Processes the TCP message. 1184 * 1185 * @param[in] callid The message identifier. 1186 * @param[in] call The message parameters. 1187 * @param[out] answer The message answer parameters. 1188 * @param[out] answer_count The last parameter for the actual answer in the 1189 * answer parameter. 1190 * @returns EOK on success. 1191 * @returns ENOTSUP if the message is not known. 1192 * 1193 * @see tcp_interface.h 1194 * @see IS_NET_TCP_MESSAGE() 1195 */ 1196 int 1197 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 1198 ipc_call_t *answer, int *answer_count) 1204 1199 { 1205 1200 ERROR_DECLARE; … … 1521 1516 socket = socket_port_find(&tcp_globals.sockets, timeout->port, 1522 1517 timeout->key, timeout->key_length); 1523 if (! (socket && (socket->socket_id == timeout->socket_id)))1518 if (!socket || (socket->socket_id != timeout->socket_id)) 1524 1519 goto out; 1525 1520 … … 1532 1527 if (timeout->sequence_number) { 1533 1528 // increase the timeout counter; 1534 ++socket_data->timeout_count;1529 socket_data->timeout_count++; 1535 1530 if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) { 1536 1531 // TODO release as connection lost … … 1744 1739 ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, 1745 1740 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))) { 1746 1747 1741 socket_data->addr = NULL; 1748 1742 socket_data->addrlen = 0; 1749 1743 fibril_rwlock_write_lock(&tcp_globals.lock); 1750 1751 1744 } else { 1752 1753 1745 packet = tcp_get_packets_to_send(socket, socket_data); 1754 1746 if (packet) { … … 1876 1868 packet = pq_next(packet); 1877 1869 // overflow occurred ? 1878 if ( (!packet)&&1870 if (!packet && 1879 1871 (socket_data->last_outgoing > socket_data->next_outgoing)) { 1880 1872 printf("gpts overflow\n"); … … 2044 2036 int 2045 2037 tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, 2046 size_t * 2038 size_t *addrlen) 2047 2039 { 2048 2040 ERROR_DECLARE; … … 2099 2091 int 2100 2092 tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, 2101 size_t * 2093 size_t *data_fragment_size, int flags) 2102 2094 { 2103 2095 ERROR_DECLARE; … … 2138 2130 packet_dimension->content : socket_data->data_fragment_size); 2139 2131 2140 for (index = 0; index < fragments; ++index) {2132 for (index = 0; index < fragments; index++) { 2141 2133 // read the data fragment 2142 2134 result = tl_socket_read_packet_data(tcp_globals.net_phone, … … 2235 2227 2236 2228 int 2237 tcp_create_notification_packet(packet_t * 2229 tcp_create_notification_packet(packet_t *packet, socket_core_ref socket, 2238 2230 tcp_socket_data_ref socket_data, int synchronize, int finalize) 2239 2231 { … … 2271 2263 int 2272 2264 tcp_accept_message(socket_cores_ref local_sockets, int socket_id, 2273 int new_socket_id, size_t * data_fragment_size, size_t *addrlen)2265 int new_socket_id, size_t *data_fragment_size, size_t *addrlen) 2274 2266 { 2275 2267 ERROR_DECLARE; … … 2373 2365 } 2374 2366 2367 /** Releases the packet and returns the result. 2368 * 2369 * @param[in] packet The packet queue to be released. 2370 * @param[in] result The result to be returned. 2371 * @return The result parameter. 2372 */ 2375 2373 int tcp_release_and_return(packet_t packet, int result) 2376 2374 { … … 2381 2379 /** Default thread for new connections. 2382 2380 * 2383 * @param[in] iidThe initial message identifier.2384 * @param[in] icallThe initial message call structure.2381 * @param[in] iid The initial message identifier. 2382 * @param[in] icall The initial message call structure. 2385 2383 * 2386 2384 */ … … 2397 2395 int answer_count; 2398 2396 2399 /* 2400 Clear the answer structure 2401 */ 2397 /* Clear the answer structure */ 2402 2398 refresh_answer(&answer, &answer_count); 2403 2399 2404 /* 2405 Fetch the next message 2406 */ 2400 /* Fetch the next message */ 2407 2401 ipc_call_t call; 2408 2402 ipc_callid_t callid = async_get_call(&call); 2409 2403 2410 /* 2411 Process the message 2412 */ 2404 /* Process the message */ 2413 2405 int res = tl_module_message_standalone(callid, &call, &answer, 2414 2406 &answer_count); 2415 2407 2416 2408 /* 2417 End if said to either by the message or the processing result 2409 * End if told to either by the message or the processing 2410 * result. 2418 2411 */ 2419 2412 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || … … 2430 2423 /** Starts the module. 2431 2424 * 2432 * @param argc The count of the command line arguments. Ignored parameter. 2433 * @param argv The command line parameters. Ignored parameter. 2434 * 2435 * @returns EOK on success. 2436 * @returns Other error codes as defined for each specific module start function. 2437 * 2425 * @returns EOK on success. 2426 * @returns Other error codes as defined for each specific module 2427 * start function. 2438 2428 */ 2439 2429 int
Note:
See TracChangeset
for help on using the changeset viewer.