Changes in uspace/srv/net/tl/tcp/tcp.c [46d4d9f:ffa2c8ef] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/tcp.c
r46d4d9f rffa2c8ef 36 36 */ 37 37 38 #include "tcp.h"39 #include "tcp_header.h"40 #include "tcp_module.h"41 42 38 #include <assert.h> 43 39 #include <async.h> … … 48 44 #include <errno.h> 49 45 50 #include <ipc/ipc.h>51 46 #include <ipc/services.h> 52 47 #include <ipc/net.h> … … 68 63 #include <ip_interface.h> 69 64 #include <icmp_client.h> 70 #include <icmp_ interface.h>65 #include <icmp_remote.h> 71 66 #include <net_interface.h> 72 67 #include <socket_core.h> 73 68 #include <tl_common.h> 74 #include <tl_local.h> 75 #include <tl_interface.h> 69 #include <tl_remote.h> 70 #include <tl_skel.h> 71 72 #include "tcp.h" 73 #include "tcp_header.h" 76 74 77 75 /** TCP module name. */ 78 #define NAME "TCP protocol"76 #define NAME "tcp" 79 77 80 78 /** The TCP window default value. */ … … 154 152 155 153 /** Port map key. */ 156 char*key;154 uint8_t *key; 157 155 158 156 /** Port map key length. */ … … 205 203 static int tcp_queue_received_packet(socket_core_t *, tcp_socket_data_t *, 206 204 packet_t *, int, size_t); 205 static void tcp_queue_received_end_of_data(socket_core_t *socket); 207 206 208 207 static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t); … … 219 218 /** TCP global data. */ 220 219 tcp_globals_t tcp_globals; 221 222 /** Initializes the TCP module.223 *224 * @param[in] client_connection The client connection processing function. The225 * module skeleton propagates its own one.226 * @return EOK on success.227 * @return ENOMEM if there is not enough memory left.228 */229 int tcp_initialize(async_client_conn_t client_connection)230 {231 int rc;232 233 assert(client_connection);234 235 fibril_rwlock_initialize(&tcp_globals.lock);236 fibril_rwlock_write_lock(&tcp_globals.lock);237 238 tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,239 ICMP_CONNECT_TIMEOUT);240 tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,241 SERVICE_TCP, client_connection);242 if (tcp_globals.ip_phone < 0) {243 fibril_rwlock_write_unlock(&tcp_globals.lock);244 return tcp_globals.ip_phone;245 }246 247 rc = socket_ports_initialize(&tcp_globals.sockets);248 if (rc != EOK)249 goto out;250 251 rc = packet_dimensions_initialize(&tcp_globals.dimensions);252 if (rc != EOK) {253 socket_ports_destroy(&tcp_globals.sockets);254 goto out;255 }256 257 tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;258 259 out:260 fibril_rwlock_write_unlock(&tcp_globals.lock);261 return rc;262 }263 220 264 221 int tcp_received_msg(device_id_t device_id, packet_t *packet, … … 357 314 /* Find the destination socket */ 358 315 socket = socket_port_find(&tcp_globals.sockets, 359 ntohs(header->destination_port), ( const char*) src, addrlen);316 ntohs(header->destination_port), (uint8_t *) src, addrlen); 360 317 if (!socket) { 361 318 /* Find the listening destination socket */ 362 319 socket = socket_port_find(&tcp_globals.sockets, 363 ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING,364 0);320 ntohs(header->destination_port), 321 (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0); 365 322 } 366 323 … … 453 410 454 411 has_error_service: 455 fibril_rwlock_ read_unlock(&tcp_globals.lock);412 fibril_rwlock_write_unlock(&tcp_globals.lock); 456 413 457 414 /* TODO error reporting/handling */ … … 504 461 size_t offset; 505 462 uint32_t new_sequence_number; 463 bool forced_ack; 506 464 int rc; 507 465 … … 512 470 assert(packet); 513 471 472 forced_ack = false; 473 514 474 new_sequence_number = ntohl(header->sequence_number); 515 475 old_incoming = socket_data->next_incoming; 516 476 517 if (header->finalize) 518 socket_data->fin_incoming = new_sequence_number; 477 if (header->finalize) { 478 socket_data->fin_incoming = new_sequence_number + 479 total_length - TCP_HEADER_LENGTH(header); 480 } 519 481 520 482 /* Trim begining if containing expected data */ … … 760 722 /* Release duplicite or restricted */ 761 723 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 762 } 763 764 /* Change state according to the acknowledging incoming fin */ 765 if (IS_IN_INTERVAL_OVERFLOW(old_incoming, socket_data->fin_incoming, 766 socket_data->next_incoming)) { 724 forced_ack = true; 725 } 726 727 /* If next in sequence is an incoming FIN */ 728 if (socket_data->next_incoming == socket_data->fin_incoming) { 729 /* Advance sequence number */ 730 socket_data->next_incoming += 1; 731 732 /* Handle FIN */ 767 733 switch (socket_data->state) { 768 734 case TCP_SOCKET_FIN_WAIT_1: … … 771 737 socket_data->state = TCP_SOCKET_CLOSING; 772 738 break; 773 /*case TCP_ESTABLISHED:*/ 739 case TCP_SOCKET_ESTABLISHED: 740 /* Queue end-of-data marker on the socket. */ 741 tcp_queue_received_end_of_data(socket); 742 socket_data->state = TCP_SOCKET_CLOSE_WAIT; 743 break; 774 744 default: 775 745 socket_data->state = TCP_SOCKET_CLOSE_WAIT; … … 779 749 780 750 packet = tcp_get_packets_to_send(socket, socket_data); 781 if (!packet ) {751 if (!packet && (socket_data->next_incoming != old_incoming || forced_ack)) { 782 752 /* Create the notification packet */ 783 753 rc = tcp_create_notification_packet(&packet, socket, … … 829 799 /* Notify the destination socket */ 830 800 async_msg_5(socket->phone, NET_SOCKET_RECEIVED, 831 ( ipcarg_t) socket->socket_id,801 (sysarg_t) socket->socket_id, 832 802 ((packet_dimension->content < socket_data->data_fragment_size) ? 833 803 packet_dimension->content : socket_data->data_fragment_size), 0, 0, 834 ( ipcarg_t) fragments);804 (sysarg_t) fragments); 835 805 836 806 return EOK; 807 } 808 809 /** Queue end-of-data marker on the socket. 810 * 811 * Next element in the sequence space is FIN. Queue end-of-data marker 812 * on the socket. 813 * 814 * @param socket Socket 815 */ 816 static void tcp_queue_received_end_of_data(socket_core_t *socket) 817 { 818 assert(socket != NULL); 819 820 /* Notify the destination socket */ 821 async_msg_5(socket->phone, NET_SOCKET_RECEIVED, 822 (sysarg_t) socket->socket_id, 823 0, 0, 0, 824 (sysarg_t) 0 /* 0 fragments == no more data */); 837 825 } 838 826 … … 966 954 /* Find the destination socket */ 967 955 listening_socket = socket_port_find(&tcp_globals.sockets, 968 listening_port, SOCKET_MAP_KEY_LISTENING, 0);956 listening_port, (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0); 969 957 if (!listening_socket || 970 958 (listening_socket->socket_id != listening_socket_id)) { … … 990 978 991 979 rc = socket_port_add(&tcp_globals.sockets, listening_port, socket, 992 ( const char*) socket_data->addr, socket_data->addrlen);980 (uint8_t *) socket_data->addr, socket_data->addrlen); 993 981 assert(socket == socket_port_find(&tcp_globals.sockets, listening_port, 994 ( const char*) socket_data->addr, socket_data->addrlen));982 (uint8_t *) socket_data->addr, socket_data->addrlen)); 995 983 996 984 // rc = socket_bind_free_port(&tcp_globals.sockets, socket, … … 1090 1078 /* Notify the destination socket */ 1091 1079 async_msg_5(socket->phone, NET_SOCKET_ACCEPTED, 1092 ( ipcarg_t) listening_socket->socket_id,1080 (sysarg_t) listening_socket->socket_id, 1093 1081 socket_data->data_fragment_size, TCP_HEADER_SIZE, 1094 0, ( ipcarg_t) socket->socket_id);1082 0, (sysarg_t) socket->socket_id); 1095 1083 1096 1084 fibril_rwlock_write_unlock(socket_data->local_lock); … … 1215 1203 } 1216 1204 1205 /** Per-connection initialization 1206 * 1207 */ 1208 void tl_connection(void) 1209 { 1210 } 1211 1217 1212 /** Processes the TCP message. 1218 1213 * … … 1228 1223 * @see IS_NET_TCP_MESSAGE() 1229 1224 */ 1230 int 1231 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 1232 ipc_call_t *answer, int *answer_count) 1233 { 1234 packet_t *packet; 1235 int rc; 1236 1225 int tl_message(ipc_callid_t callid, ipc_call_t *call, 1226 ipc_call_t *answer, size_t *answer_count) 1227 { 1237 1228 assert(call); 1238 1229 assert(answer); … … 1240 1231 1241 1232 *answer_count = 0; 1242 switch (IPC_GET_METHOD(*call)) { 1243 case NET_TL_RECEIVED: 1244 // fibril_rwlock_read_lock(&tcp_globals.lock); 1245 rc = packet_translate_remote(tcp_globals.net_phone, &packet, 1246 IPC_GET_PACKET(call)); 1247 if (rc != EOK) { 1248 // fibril_rwlock_read_unlock(&tcp_globals.lock); 1249 return rc; 1250 } 1251 rc = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP, 1252 IPC_GET_ERROR(call)); 1253 // fibril_rwlock_read_unlock(&tcp_globals.lock); 1254 return rc; 1233 switch (IPC_GET_IMETHOD(*call)) { 1255 1234 case IPC_M_CONNECT_TO_ME: 1256 1235 return tcp_process_client_messages(callid, *call); … … 1291 1270 bool keep_on_going = true; 1292 1271 socket_cores_t local_sockets; 1293 int app_phone = IPC_GET_PHONE( &call);1272 int app_phone = IPC_GET_PHONE(call); 1294 1273 struct sockaddr *addr; 1295 1274 int socket_id; … … 1298 1277 fibril_rwlock_t lock; 1299 1278 ipc_call_t answer; 1300 int answer_count;1279 size_t answer_count; 1301 1280 tcp_socket_data_t *socket_data; 1302 1281 socket_core_t *socket; … … 1323 1302 1324 1303 /* Process the call */ 1325 switch (IPC_GET_ METHOD(call)) {1304 switch (IPC_GET_IMETHOD(call)) { 1326 1305 case IPC_M_PHONE_HUNGUP: 1327 1306 keep_on_going = false; … … 1365 1344 1366 1345 case NET_SOCKET_BIND: 1367 res = data_receive((void **) &addr, &addrlen); 1346 res = async_data_write_accept((void **) &addr, false, 1347 0, 0, 0, &addrlen); 1368 1348 if (res != EOK) 1369 1349 break; … … 1402 1382 1403 1383 case NET_SOCKET_CONNECT: 1404 res = data_receive((void **) &addr, &addrlen); 1384 res = async_data_write_accept((void **) &addr, false, 1385 0, 0, 0, &addrlen); 1405 1386 if (res != EOK) 1406 1387 break; … … 1453 1434 1454 1435 case NET_SOCKET_SENDTO: 1455 res = data_receive((void **) &addr, &addrlen); 1436 res = async_data_write_accept((void **) &addr, false, 1437 0, 0, 0, &addrlen); 1456 1438 if (res != EOK) 1457 1439 break; … … 1523 1505 1524 1506 /* Release the application phone */ 1525 ipc_hangup(app_phone);1507 async_hangup(app_phone); 1526 1508 1527 1509 printf("release\n"); … … 1800 1782 fibril_rwlock_write_unlock(socket_data->local_lock); 1801 1783 1784 socket_data->state = TCP_SOCKET_SYN_SENT; 1785 1802 1786 /* Send the packet */ 1803 1787 printf("connecting %d\n", packet_get_id(packet)); … … 2072 2056 2073 2057 /* Copy the key */ 2074 operation_timeout->key = (( char*) operation_timeout) +2058 operation_timeout->key = ((uint8_t *) operation_timeout) + 2075 2059 sizeof(*operation_timeout); 2076 2060 operation_timeout->key_length = socket->key_length; … … 2082 2066 if (!fibril) { 2083 2067 free(operation_timeout); 2084 return EPARTY; /* FIXME: use another EC */ 2085 } 2068 return ENOMEM; 2069 } 2070 2086 2071 // fibril_mutex_lock(&socket_data->operation.mutex); 2087 2072 /* Start the timeout fibril */ … … 2206 2191 2207 2192 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); 2208 rc = tcp_queue_packet(socket, socket_data, packet, 0);2193 rc = tcp_queue_packet(socket, socket_data, packet, total_length); 2209 2194 if (rc != EOK) 2210 2195 return rc; … … 2448 2433 } 2449 2434 2450 /** Default thread for new connections.2435 /** Process IPC messages from the IP module 2451 2436 * 2452 * @param[in] iid The initial message identifier.2453 * @param[in ] icall The initial message call structure.2437 * @param[in] iid Message identifier. 2438 * @param[in,out] icall Message parameters. 2454 2439 * 2455 2440 */ 2456 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall) 2457 { 2458 /* 2459 * Accept the connection 2460 * - Answer the first IPC_M_CONNECT_ME_TO call. 2461 */ 2462 ipc_answer_0(iid, EOK); 2463 2441 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall) 2442 { 2443 packet_t *packet; 2444 int rc; 2445 2464 2446 while (true) { 2465 ipc_call_t answer; 2466 int answer_count; 2467 2468 /* Clear the answer structure */ 2469 refresh_answer(&answer, &answer_count); 2470 2471 /* Fetch the next message */ 2472 ipc_call_t call; 2473 ipc_callid_t callid = async_get_call(&call); 2474 2475 /* Process the message */ 2476 int res = tl_module_message_standalone(callid, &call, &answer, 2477 &answer_count); 2478 2479 /* 2480 * End if told to either by the message or the processing 2481 * result. 2482 */ 2483 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || 2484 (res == EHANGUP)) 2485 return; 2486 2487 /* 2488 * Answer the message 2489 */ 2490 answer_call(callid, res, &answer, answer_count); 2491 } 2492 } 2493 2494 /** Starts the module. 2447 switch (IPC_GET_IMETHOD(*icall)) { 2448 case NET_TL_RECEIVED: 2449 rc = packet_translate_remote(tcp_globals.net_phone, &packet, 2450 IPC_GET_PACKET(*icall)); 2451 if (rc == EOK) 2452 rc = tcp_received_msg(IPC_GET_DEVICE(*icall), packet, 2453 SERVICE_TCP, IPC_GET_ERROR(*icall)); 2454 2455 async_answer_0(iid, (sysarg_t) rc); 2456 break; 2457 default: 2458 async_answer_0(iid, (sysarg_t) ENOTSUP); 2459 } 2460 2461 iid = async_get_call(icall); 2462 } 2463 } 2464 2465 /** Initialize the TCP module. 2495 2466 * 2496 * @return EOK on success. 2497 * @return Other error codes as defined for each specific module 2498 * start function. 2467 * @param[in] net_phone Network module phone. 2468 * 2469 * @return EOK on success. 2470 * @return ENOMEM if there is not enough memory left. 2471 * 2499 2472 */ 2500 int 2501 main(int argc, char *argv[]) 2502 { 2503 int rc; 2504 2505 rc = tl_module_start_standalone(tl_client_connection); 2473 int tl_initialize(int net_phone) 2474 { 2475 fibril_rwlock_initialize(&tcp_globals.lock); 2476 fibril_rwlock_write_lock(&tcp_globals.lock); 2477 2478 tcp_globals.net_phone = net_phone; 2479 2480 tcp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT); 2481 tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, 2482 SERVICE_TCP, tcp_receiver); 2483 if (tcp_globals.ip_phone < 0) { 2484 fibril_rwlock_write_unlock(&tcp_globals.lock); 2485 return tcp_globals.ip_phone; 2486 } 2487 2488 int rc = socket_ports_initialize(&tcp_globals.sockets); 2489 if (rc != EOK) 2490 goto out; 2491 2492 rc = packet_dimensions_initialize(&tcp_globals.dimensions); 2493 if (rc != EOK) { 2494 socket_ports_destroy(&tcp_globals.sockets); 2495 goto out; 2496 } 2497 2498 tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1; 2499 2500 out: 2501 fibril_rwlock_write_unlock(&tcp_globals.lock); 2506 2502 return rc; 2503 } 2504 2505 int main(int argc, char *argv[]) 2506 { 2507 return tl_module_start(SERVICE_TCP); 2507 2508 } 2508 2509
Note:
See TracChangeset
for help on using the changeset viewer.