Changes in uspace/srv/net/tl/tcp/tcp.c [fb04cba8:0578271] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/tcp/tcp.c
rfb04cba8 r0578271 44 44 #include <fibril_synch.h> 45 45 #include <malloc.h> 46 / * TODO remove stdio */46 //TODO remove stdio 47 47 #include <stdio.h> 48 48 #include <errno.h> … … 267 267 } 268 268 269 int tcp_received_msg(device_id_t device_id, packet_t packet, 270 services_t receiver, services_t error) 269 int 270 tcp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, 271 services_t error) 271 272 { 272 273 int rc; … … 308 309 break; 309 310 case SERVICE_ICMP: 310 / * Process error */311 // process error 311 312 result = icmp_client_process_packet(packet, &type, &code, NULL, 312 313 NULL); … … 323 324 } 324 325 325 / * TODO process received ipopts? */326 // TODO process received ipopts? 326 327 result = ip_client_process_packet(packet, NULL, NULL, NULL, NULL, NULL); 327 328 if (result < 0) … … 337 338 return tcp_release_and_return(packet, NO_DATA); 338 339 339 / * Trim all but TCP header */340 // trim all but TCP header 340 341 rc = packet_trim(packet, offset, 0); 341 342 if (rc != EOK) 342 343 return tcp_release_and_return(packet, rc); 343 344 344 / * Get tcp header */345 // get tcp header 345 346 header = (tcp_header_ref) packet_get_data(packet); 346 347 if (!header) … … 360 361 return tcp_release_and_return(packet, rc); 361 362 362 / * Find the destination socket */363 // find the destination socket 363 364 socket = socket_port_find(&tcp_globals.sockets, 364 365 ntohs(header->destination_port), (const char *) src, addrlen); 365 366 if (!socket) { 366 / * Find the listening destination socket */367 // find the listening destination socket 367 368 socket = socket_port_find(&tcp_globals.sockets, 368 369 ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 369 370 0); 370 371 } 371 372 372 if (!socket) { 373 373 if (tl_prepare_icmp_packet(tcp_globals.net_phone, … … 383 383 assert(socket_data); 384 384 385 / * Some data received, clear the timeout counter */385 // some data received, clear the timeout counter 386 386 socket_data->timeout_count = 0; 387 387 388 / * Count the received packet fragments */388 // count the received packet fragments 389 389 next_packet = packet; 390 390 fragments = 0; … … 399 399 total_length += length; 400 400 401 / * Add partial checksum if set */401 // add partial checksum if set 402 402 if (!error) { 403 403 checksum = compute_checksum(checksum, … … 447 447 tcp_globals.icmp_phone, packet, error); 448 448 if (rc == EOK) { 449 / * Checksum error ICMP */449 // checksum error ICMP 450 450 icmp_parameter_problem_msg(tcp_globals.icmp_phone, 451 451 ICMP_PARAM_POINTER, … … 460 460 fibril_rwlock_read_unlock(&tcp_globals.lock); 461 461 462 / * TODO error reporting/handling */462 // TODO error reporting/handling 463 463 switch (socket_data->state) { 464 464 case TCP_SOCKET_LISTEN: … … 474 474 break; 475 475 case TCP_SOCKET_FIN_WAIT_1: 476 / * ack changing the state to FIN_WAIT_2 gets processed later */476 // ack changing the state to FIN_WAIT_2 gets processed later 477 477 case TCP_SOCKET_FIN_WAIT_2: 478 / * fin changing state to LAST_ACK gets processed later */478 // fin changing state to LAST_ACK gets processed later 479 479 case TCP_SOCKET_LAST_ACK: 480 / * ack releasing the socket get processed later */480 // ack releasing the socket get processed later 481 481 case TCP_SOCKET_CLOSING: 482 / * ack releasing the socket gets processed later */482 // ack releasing the socket gets processed later 483 483 case TCP_SOCKET_ESTABLISHED: 484 484 rc = tcp_process_established(socket, socket_data, header, … … 497 497 } 498 498 499 int tcp_process_established(socket_core_ref socket, tcp_socket_data_ref500 socket_data, tcp_header_ref header, packet_t packet, int fragments,501 size_t total_length)499 int 500 tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, 501 tcp_header_ref header, packet_t packet, int fragments, size_t total_length) 502 502 { 503 503 packet_t next_packet; … … 523 523 socket_data->fin_incoming = new_sequence_number; 524 524 525 / * Trim begining if containing expected data */525 // trim begining if containing expected data 526 526 if (IS_IN_INTERVAL_OVERFLOW(new_sequence_number, 527 527 socket_data->next_incoming, new_sequence_number + total_length)) { 528 528 529 / * Get the acknowledged offset */529 // get the acknowledged offset 530 530 if (socket_data->next_incoming < new_sequence_number) { 531 531 offset = new_sequence_number - … … 539 539 total_length -= offset; 540 540 length = packet_get_data_length(packet); 541 542 /* Trim the acknowledged data */ 541 // trim the acknowledged data 543 542 while (length <= offset) { 544 / * Release the acknowledged packets */543 // release the acknowledged packets 545 544 next_packet = pq_next(packet); 546 545 pq_release_remote(tcp_globals.net_phone, … … 560 559 } 561 560 562 / * Release if overflowing the window */561 // release if overflowing the window 563 562 /* 564 563 if (IS_IN_INTERVAL_OVERFLOW(socket_data->next_incoming + … … 610 609 } 611 610 */ 612 / * The expected one arrived? */611 // the expected one arrived? 613 612 if (new_sequence_number == socket_data->next_incoming) { 614 613 printf("expected\n"); 615 / * Process acknowledgement */614 // process acknowledgement 616 615 tcp_process_acknowledgement(socket, socket_data, header); 617 616 618 / * Remove the header */617 // remove the header 619 618 total_length -= TCP_HEADER_LENGTH(header); 620 619 rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0); … … 636 635 rc = pq_get_order(socket_data->incoming, &order, NULL); 637 636 if (rc != EOK) { 638 / * Remove the corrupted packet */637 // remove the corrupted packet 639 638 next_packet = pq_detach(packet); 640 639 if (packet == socket_data->incoming) … … 649 648 if (IS_IN_INTERVAL_OVERFLOW(sequence_number, 650 649 old_incoming, socket_data->next_incoming)) { 651 / * Move to the next */650 // move to the next 652 651 packet = pq_next(packet); 653 / * Coninual data? */652 // coninual data? 654 653 } else if (IS_IN_INTERVAL_OVERFLOW(old_incoming, 655 654 sequence_number, socket_data->next_incoming)) { 656 / * Detach the packet */655 // detach the packet 657 656 next_packet = pq_detach(packet); 658 657 if (packet == socket_data->incoming) 659 658 socket_data->incoming = next_packet; 660 / * Get data length */659 // get data length 661 660 length = packet_get_data_length(packet); 662 661 new_sequence_number = sequence_number + length; 663 662 if (length <= 0) { 664 / * Remove the empty packet */663 // remove the empty packet 665 664 pq_release_remote(tcp_globals.net_phone, 666 665 packet_get_id(packet)); … … 668 667 continue; 669 668 } 670 / * Exactly following */669 // exactly following 671 670 if (sequence_number == 672 671 socket_data->next_incoming) { 673 / * Queue received data */672 // queue received data 674 673 rc = tcp_queue_received_packet(socket, 675 674 socket_data, packet, 1, … … 681 680 packet = next_packet; 682 681 continue; 683 / * At least partly following data? */682 // at least partly following data? 684 683 } 685 684 if (IS_IN_INTERVAL_OVERFLOW(sequence_number, … … 696 695 rc = packet_trim(packet,length, 0); 697 696 if (rc == EOK) { 698 / * Queue received data */697 // queue received data 699 698 rc = tcp_queue_received_packet( 700 699 socket, socket_data, packet, … … 709 708 } 710 709 } 711 / * Remove the duplicit or corrupted packet */710 // remove the duplicit or corrupted packet 712 711 pq_release_remote(tcp_globals.net_phone, 713 712 packet_get_id(packet)); … … 722 721 socket_data->next_incoming + socket_data->window)) { 723 722 printf("in window\n"); 724 / * Process acknowledgement */723 // process acknowledgement 725 724 tcp_process_acknowledgement(socket, socket_data, header); 726 725 727 / * Remove the header */726 // remove the header 728 727 total_length -= TCP_HEADER_LENGTH(header); 729 728 rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0); … … 736 735 length); 737 736 if (rc != EOK) { 738 / * Remove the corrupted packets */737 // remove the corrupted packets 739 738 pq_release_remote(tcp_globals.net_phone, 740 739 packet_get_id(packet)); … … 763 762 } else { 764 763 printf("unexpected\n"); 765 / * Release duplicite or restricted */764 // release duplicite or restricted 766 765 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 767 766 } 768 767 769 / * Change state according to the acknowledging incoming fin */768 // change state according to the acknowledging incoming fin 770 769 if (IS_IN_INTERVAL_OVERFLOW(old_incoming, socket_data->fin_incoming, 771 770 socket_data->next_incoming)) { … … 776 775 socket_data->state = TCP_SOCKET_CLOSING; 777 776 break; 778 /*case TCP_ESTABLISHED:*/777 //case TCP_ESTABLISHED: 779 778 default: 780 779 socket_data->state = TCP_SOCKET_CLOSE_WAIT; … … 785 784 packet = tcp_get_packets_to_send(socket, socket_data); 786 785 if (!packet) { 787 / * Create the notification packet */786 // create the notification packet 788 787 rc = tcp_create_notification_packet(&packet, socket, 789 788 socket_data, 0, 0); … … 799 798 fibril_rwlock_write_unlock(socket_data->local_lock); 800 799 801 / * Send the packet */800 // send the packet 802 801 tcp_send_packets(socket_data->device_id, packet); 803 802 … … 805 804 } 806 805 807 int tcp_queue_received_packet(socket_core_ref socket, 806 int 807 tcp_queue_received_packet(socket_core_ref socket, 808 808 tcp_socket_data_ref socket_data, packet_t packet, int fragments, 809 809 size_t total_length) … … 819 819 assert(socket_data->window > total_length); 820 820 821 / * Queue the received packet */821 // queue the received packet 822 822 rc = dyn_fifo_push(&socket->received, packet_get_id(packet), 823 823 SOCKET_MAX_RECEIVED_SIZE); … … 829 829 return tcp_release_and_return(packet, rc); 830 830 831 / * Decrease the window size */831 // decrease the window size 832 832 socket_data->window -= total_length; 833 833 834 / * Notify the destination socket */834 // notify the destination socket 835 835 async_msg_5(socket->phone, NET_SOCKET_RECEIVED, 836 836 (ipcarg_t) socket->socket_id, … … 842 842 } 843 843 844 int tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref 845 socket_data, tcp_header_ref header, packet_t packet) 844 int 845 tcp_process_syn_sent(socket_core_ref socket, tcp_socket_data_ref socket_data, 846 tcp_header_ref header, packet_t packet) 846 847 { 847 848 packet_t next_packet; … … 857 858 return tcp_release_and_return(packet, EINVAL); 858 859 859 / * Process acknowledgement */860 // process acknowledgement 860 861 tcp_process_acknowledgement(socket, socket_data, header); 861 862 862 863 socket_data->next_incoming = ntohl(header->sequence_number) + 1; 863 864 /* Release additional packets */ 864 // release additional packets 865 865 next_packet = pq_detach(packet); 866 866 if (next_packet) { … … 868 868 packet_get_id(next_packet)); 869 869 } 870 871 /* Trim if longer than the header */ 870 // trim if longer than the header 872 871 if (packet_get_data_length(packet) > sizeof(*header)) { 873 872 rc = packet_trim(packet, 0, … … 876 875 return tcp_release_and_return(packet, rc); 877 876 } 878 879 877 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); 880 878 fibril_mutex_lock(&socket_data->operation.mutex); 881 879 socket_data->operation.result = tcp_queue_packet(socket, socket_data, 882 880 packet, 1); 883 884 881 if (socket_data->operation.result == EOK) { 885 882 socket_data->state = TCP_SOCKET_ESTABLISHED; … … 887 884 if (packet) { 888 885 fibril_rwlock_write_unlock( socket_data->local_lock); 889 / * Send the packet */886 // send the packet 890 887 tcp_send_packets(socket_data->device_id, packet); 891 / * Signal the result */888 // signal the result 892 889 fibril_condvar_signal( &socket_data->operation.condvar); 893 890 fibril_mutex_unlock( &socket_data->operation.mutex); … … 895 892 } 896 893 } 897 898 894 fibril_mutex_unlock(&socket_data->operation.mutex); 899 895 return tcp_release_and_return(packet, EINVAL); 900 896 } 901 897 902 int tcp_process_listen(socket_core_ref listening_socket, 898 int 899 tcp_process_listen(socket_core_ref listening_socket, 903 900 tcp_socket_data_ref listening_socket_data, tcp_header_ref header, 904 901 packet_t packet, struct sockaddr *src, struct sockaddr *dest, … … 939 936 return tcp_release_and_return(packet, ENOMEM); 940 937 } 941 942 938 memcpy(socket_data->addr, src, socket_data->addrlen); 943 939 socket_data->dest_port = ntohs(header->source_port); … … 950 946 } 951 947 952 / * Create a socket */948 // create a socket 953 949 socket_id = -1; 954 950 rc = socket_create(socket_data->local_sockets, listening_socket->phone, … … 969 965 fibril_rwlock_write_lock(&tcp_globals.lock); 970 966 971 / * Find the destination socket */967 // find the destination socket 972 968 listening_socket = socket_port_find(&tcp_globals.sockets, 973 969 listening_port, SOCKET_MAP_KEY_LISTENING, 0); … … 975 971 (listening_socket->socket_id != listening_socket_id)) { 976 972 fibril_rwlock_write_unlock(&tcp_globals.lock); 977 / * A shadow may remain until app hangs up */973 // a shadow may remain until app hangs up 978 974 return tcp_release_and_return(packet, EOK /*ENOTSOCK*/); 979 975 } … … 987 983 socket_id); 988 984 if (!socket) { 989 / * Where is the socket?!? */985 // where is the socket?!? 990 986 fibril_rwlock_write_unlock(&tcp_globals.lock); 991 987 return ENOTSOCK; … … 1014 1010 socket_data->next_incoming = ntohl(header->sequence_number) + 1; 1015 1011 1016 / * Release additional packets */1012 // release additional packets 1017 1013 next_packet = pq_detach(packet); 1018 1014 if (next_packet) { … … 1021 1017 } 1022 1018 1023 / * Trim if longer than the header */1019 // trim if longer than the header 1024 1020 if (packet_get_data_length(packet) > sizeof(*header)) { 1025 1021 rc = packet_trim(packet, 0, … … 1054 1050 fibril_rwlock_write_unlock(socket_data->local_lock); 1055 1051 1056 / * Send the packet */1052 // send the packet 1057 1053 tcp_send_packets(socket_data->device_id, packet); 1058 1054 … … 1060 1056 } 1061 1057 1062 int tcp_process_syn_received(socket_core_ref socket, 1058 int 1059 tcp_process_syn_received(socket_core_ref socket, 1063 1060 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet) 1064 1061 { … … 1076 1073 return tcp_release_and_return(packet, EINVAL); 1077 1074 1078 / * Process acknowledgement */1075 // process acknowledgement 1079 1076 tcp_process_acknowledgement(socket, socket_data, header); 1080 1077 … … 1089 1086 assert(listening_socket_data); 1090 1087 1091 / * Queue the received packet */1088 // queue the received packet 1092 1089 rc = dyn_fifo_push(&listening_socket->accepted, 1093 1090 (-1 * socket->socket_id), listening_socket_data->backlog); 1094 1091 if (rc == EOK) { 1095 / * Notify the destination socket */1092 // notify the destination socket 1096 1093 async_msg_5(socket->phone, NET_SOCKET_ACCEPTED, 1097 1094 (ipcarg_t) listening_socket->socket_id, … … 1103 1100 } 1104 1101 } 1105 / * Send FIN */1102 // send FIN 1106 1103 socket_data->state = TCP_SOCKET_FIN_WAIT_1; 1107 1104 1108 / * Create the notification packet */1105 // create the notification packet 1109 1106 rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1); 1110 1107 if (rc != EOK) 1111 1108 return rc; 1112 1109 1113 / * Send the packet */1110 // send the packet 1114 1111 rc = tcp_queue_packet(socket, socket_data, packet, 1); 1115 1112 if (rc != EOK) 1116 1113 return rc; 1117 1114 1118 / * Flush packets */1115 // flush packets 1119 1116 packet = tcp_get_packets_to_send(socket, socket_data); 1120 1117 fibril_rwlock_write_unlock(socket_data->local_lock); 1121 1118 if (packet) { 1122 / * Send the packet */1119 // send the packet 1123 1120 tcp_send_packets(socket_data->device_id, packet); 1124 1121 } … … 1127 1124 } 1128 1125 1129 void tcp_process_acknowledgement(socket_core_ref socket, 1126 void 1127 tcp_process_acknowledgement(socket_core_ref socket, 1130 1128 tcp_socket_data_ref socket_data, tcp_header_ref header) 1131 1129 { … … 1146 1144 1147 1145 number = ntohl(header->acknowledgement_number); 1148 1149 /* If more data acknowledged */ 1146 // if more data acknowledged 1150 1147 if (number != socket_data->expected) { 1151 1148 old = socket_data->expected; … … 1158 1155 case TCP_SOCKET_LAST_ACK: 1159 1156 case TCP_SOCKET_CLOSING: 1160 /* 1161 * FIN acknowledged - release the socket in 1162 * another fibril. 1163 */ 1157 // fin acknowledged - release the socket in 1158 // another fibril 1164 1159 tcp_prepare_timeout(tcp_release_after_timeout, 1165 1160 socket, socket_data, 0, … … 1171 1166 } 1172 1167 } 1173 1174 /* Update the treshold if higher than set */ 1168 // update the treshold if higher than set 1175 1169 if (number + ntohs(header->window) > 1176 1170 socket_data->expected + socket_data->treshold) { … … 1178 1172 socket_data->expected; 1179 1173 } 1180 1181 /* Set new expected sequence number */ 1174 // set new expected sequence number 1182 1175 socket_data->expected = number; 1183 1176 socket_data->expected_count = 1; … … 1191 1184 socket_data->outgoing = next; 1192 1185 1193 / * Add to acknowledged or release */1186 // add to acknowledged or release 1194 1187 if (pq_add(&acknowledged, packet, 0, 0) != EOK) 1195 1188 pq_release_remote(tcp_globals.net_phone, … … 1199 1192 break; 1200 1193 } 1201 1202 /* Release acknowledged */ 1194 // release acknowledged 1203 1195 if (acknowledged) { 1204 1196 pq_release_remote(tcp_globals.net_phone, … … 1206 1198 } 1207 1199 return; 1208 /* If the same as the previous time */ 1209 } 1210 1200 // if the same as the previous time 1201 } 1211 1202 if (number == socket_data->expected) { 1212 / * Increase the counter */1203 // increase the counter 1213 1204 socket_data->expected_count++; 1214 1205 if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) { 1215 1206 socket_data->expected_count = 1; 1216 / * TODO retransmit lock */1207 // TODO retransmit lock 1217 1208 //tcp_retransmit_packet(socket, socket_data, number); 1218 1209 } … … 1320 1311 while (keep_on_going) { 1321 1312 1322 / * Answer the call */1313 // answer the call 1323 1314 answer_call(callid, res, &answer, answer_count); 1324 / * Refresh data */1315 // refresh data 1325 1316 refresh_answer(&answer, &answer_count); 1326 / * Get the next call */1317 // get the next call 1327 1318 callid = async_get_call(&call); 1328 1319 1329 / * Process the call */1320 // process the call 1330 1321 switch (IPC_GET_METHOD(call)) { 1331 1322 case IPC_M_PHONE_HUNGUP: … … 1410 1401 if (res != EOK) 1411 1402 break; 1412 /* 1413 * The global lock may be released in the 1414 * tcp_connect_message() function. 1415 */ 1403 // the global lock may be released in the 1404 // tcp_connect_message() function 1416 1405 fibril_rwlock_write_lock(&tcp_globals.lock); 1417 1406 fibril_rwlock_write_lock(&lock); … … 1527 1516 } 1528 1517 1529 / * Release the application phone */1518 // release the application phone 1530 1519 ipc_hangup(app_phone); 1531 1520 1532 1521 printf("release\n"); 1533 / * Release all local sockets */1522 // release all local sockets 1534 1523 socket_cores_release(tcp_globals.net_phone, &local_sockets, 1535 1524 &tcp_globals.sockets, tcp_free_socket_data); … … 1547 1536 assert(timeout); 1548 1537 1549 / * Sleep the given timeout */1538 // sleep the given timeout 1550 1539 async_usleep(timeout->timeout); 1551 / * Lock the globals */1540 // lock the globals 1552 1541 if (timeout->globals_read_only) 1553 1542 fibril_rwlock_read_lock(&tcp_globals.lock); … … 1555 1544 fibril_rwlock_write_lock(&tcp_globals.lock); 1556 1545 1557 / * Find the pending operation socket */1546 // find the pending operation socket 1558 1547 socket = socket_port_find(&tcp_globals.sockets, timeout->port, 1559 1548 timeout->key, timeout->key_length); … … 1568 1557 fibril_rwlock_write_lock(socket_data->local_lock); 1569 1558 if (timeout->sequence_number) { 1570 / * Increase the timeout counter */1559 // increase the timeout counter; 1571 1560 socket_data->timeout_count++; 1572 1561 if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) { 1573 / * TODO release as connection lost */1562 // TODO release as connection lost 1574 1563 //tcp_refresh_socket_data(socket_data); 1575 1564 fibril_rwlock_write_unlock(socket_data->local_lock); 1576 1565 } else { 1577 / * Retransmit */1566 // retransmit 1578 1567 // tcp_retransmit_packet(socket, 1579 1568 // socket_data, timeout->sequence_number); … … 1582 1571 } else { 1583 1572 fibril_mutex_lock(&socket_data->operation.mutex); 1584 /* Set the timeout operation result if state not changed */ 1573 // set the timeout operation result if state not 1574 // changed 1585 1575 if (socket_data->state == timeout->state) { 1586 1576 socket_data->operation.result = ETIMEOUT; 1587 1588 /* Notify the main fibril */ 1577 // notify the main fibril 1589 1578 fibril_condvar_signal(&socket_data->operation.condvar); 1590 1591 /* Keep the global write lock */ 1579 // keep the global write lock 1592 1580 keep_write_lock = true; 1593 1581 } else { 1594 /* 1595 * Operation is ok, do nothing. 1596 * Unlocking from now on, so the unlocking 1597 * order does not matter. 1598 */ 1582 // operation is ok, do nothing 1583 // unlocking from now on, so the unlocki 1584 // order does not matter... 1599 1585 fibril_rwlock_write_unlock(socket_data->local_lock); 1600 1586 } … … 1603 1589 1604 1590 out: 1605 / * Unlock only if no socket */1591 // unlock only if no socket 1606 1592 if (timeout->globals_read_only) 1607 1593 fibril_rwlock_read_unlock(&tcp_globals.lock); 1608 1594 else if (!keep_write_lock) 1609 / * Release if not desired */1595 // release if not desired 1610 1596 fibril_rwlock_write_unlock(&tcp_globals.lock); 1611 1597 1612 / * Release the timeout structure */1598 // release the timeout structure 1613 1599 free(timeout); 1614 1600 return EOK; … … 1624 1610 assert(timeout); 1625 1611 1626 / * Sleep the given timeout */1612 // sleep the given timeout 1627 1613 async_usleep(timeout->timeout); 1628 1629 /* Lock the globals */ 1614 // lock the globals 1630 1615 fibril_rwlock_write_lock(&tcp_globals.lock); 1631 1632 /* Find the pending operation socket */ 1616 // find the pending operation socket 1633 1617 socket = socket_port_find(&tcp_globals.sockets, timeout->port, 1634 1618 timeout->key, timeout->key_length); 1635 1636 1619 if (socket && (socket->socket_id == timeout->socket_id)) { 1637 1620 socket_data = (tcp_socket_data_ref) socket->specific_data; … … 1646 1629 } 1647 1630 } 1648 1649 /* Unlock the globals */ 1631 // unlock the globals 1650 1632 fibril_rwlock_write_unlock(&tcp_globals.lock); 1651 1652 /* Release the timeout structure */ 1633 // release the timeout structure 1653 1634 free(timeout); 1654 1655 1635 return EOK; 1656 1636 } 1657 1637 1658 void tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref 1659 socket_data, size_t sequence_number) 1638 void 1639 tcp_retransmit_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, 1640 size_t sequence_number) 1660 1641 { 1661 1642 packet_t packet; … … 1667 1648 assert(socket->specific_data == socket_data); 1668 1649 1669 / * Sent packet? */1650 // sent packet? 1670 1651 packet = pq_find(socket_data->outgoing, sequence_number); 1671 1652 printf("retransmit %d\n", packet_get_id(packet)); … … 1683 1664 } 1684 1665 1685 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id,1686 1666 int 1667 tcp_listen_message(socket_cores_ref local_sockets, int socket_id, int backlog) 1687 1668 { 1688 1669 socket_core_ref socket; … … 1694 1675 return EINVAL; 1695 1676 1696 / * Find the socket */1677 // find the socket 1697 1678 socket = socket_cores_find(local_sockets, socket_id); 1698 1679 if (!socket) 1699 1680 return ENOTSOCK; 1700 1681 1701 / * Get the socket specific data */1682 // get the socket specific data 1702 1683 socket_data = (tcp_socket_data_ref) socket->specific_data; 1703 1684 assert(socket_data); 1704 1705 /* Set the backlog */ 1685 // set the backlog 1706 1686 socket_data->backlog = backlog; 1707 1687 … … 1709 1689 } 1710 1690 1711 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, 1691 int 1692 tcp_connect_message(socket_cores_ref local_sockets, int socket_id, 1712 1693 struct sockaddr *addr, socklen_t addrlen) 1713 1694 { … … 1719 1700 assert(addrlen > 0); 1720 1701 1721 / * Find the socket */1702 // find the socket 1722 1703 socket = socket_cores_find(local_sockets, socket_id); 1723 1704 if (!socket) … … 1727 1708 if (rc != EOK) { 1728 1709 tcp_free_socket_data(socket); 1729 / * Unbind if bound */1710 // unbind if bound 1730 1711 if (socket->port > 0) { 1731 1712 socket_ports_exclude(&tcp_globals.sockets, … … 1737 1718 } 1738 1719 1739 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, 1720 int 1721 tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, 1740 1722 struct sockaddr *addr, socklen_t addrlen) 1741 1723 { … … 1748 1730 assert(addrlen > 0); 1749 1731 1750 / * Get the socket specific data */1732 // get the socket specific data 1751 1733 socket_data = (tcp_socket_data_ref) socket->specific_data; 1752 1734 assert(socket_data); … … 1757 1739 return EINVAL; 1758 1740 1759 / * Get the destination port */1741 // get the destination port 1760 1742 rc = tl_get_address_port(addr, addrlen, &socket_data->dest_port); 1761 1743 if (rc != EOK) … … 1763 1745 1764 1746 if (socket->port <= 0) { 1765 / * Try to find a free port */1747 // try to find a free port 1766 1748 rc = socket_bind_free_port(&tcp_globals.sockets, socket, 1767 1749 TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, … … 1769 1751 if (rc != EOK) 1770 1752 return rc; 1771 / * Set the next port as the search starting port number */1753 // set the next port as the search starting port number 1772 1754 tcp_globals.last_used_port = socket->port; 1773 1755 } … … 1779 1761 return rc; 1780 1762 1781 / * Create the notification packet */1763 // create the notification packet 1782 1764 rc = tcp_create_notification_packet(&packet, socket, socket_data, 1, 0); 1783 1765 if (rc != EOK) 1784 1766 return rc; 1785 1767 1786 / * Unlock the globals and wait for an operation */1768 // unlock the globals and wait for an operation 1787 1769 fibril_rwlock_write_unlock(&tcp_globals.lock); 1788 1770 1789 1771 socket_data->addr = addr; 1790 1772 socket_data->addrlen = addrlen; 1791 1792 /* Send the packet */ 1773 // send the packet 1793 1774 1794 1775 if (((rc = tcp_queue_packet(socket, socket_data, packet, 1)) != EOK) || … … 1804 1785 fibril_mutex_lock(&socket_data->operation.mutex); 1805 1786 fibril_rwlock_write_unlock(socket_data->local_lock); 1806 1807 /* Send the packet */ 1787 // send the packet 1808 1788 printf("connecting %d\n", packet_get_id(packet)); 1809 1789 tcp_send_packets(socket_data->device_id, packet); 1810 1790 1811 / * Wait for a reply */1791 // wait for a reply 1812 1792 fibril_condvar_wait(&socket_data->operation.condvar, 1813 1793 &socket_data->operation.mutex); … … 1825 1805 1826 1806 fibril_mutex_unlock(&socket_data->operation.mutex); 1807 1808 // return the result 1827 1809 return rc; 1828 1810 } 1829 1811 1830 int tcp_queue_prepare_packet(socket_core_ref socket, 1812 int 1813 tcp_queue_prepare_packet(socket_core_ref socket, 1831 1814 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length) 1832 1815 { … … 1838 1821 assert(socket->specific_data == socket_data); 1839 1822 1840 / * Get TCP header */1823 // get tcp header 1841 1824 header = (tcp_header_ref) packet_get_data(packet); 1842 1825 if (!header) … … 1852 1835 return tcp_release_and_return(packet, EINVAL); 1853 1836 1854 / * Remember the outgoing FIN */1837 // remember the outgoing FIN 1855 1838 if (header->finalize) 1856 1839 socket_data->fin_outgoing = socket_data->next_outgoing; … … 1859 1842 } 1860 1843 1861 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, 1844 int 1845 tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, 1862 1846 packet_t packet, size_t data_length) 1863 1847 { … … 1881 1865 } 1882 1866 1883 packet_t tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref1884 1867 packet_t 1868 tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data) 1885 1869 { 1886 1870 packet_t packet; … … 1899 1883 pq_get_order(packet, NULL, &data_length); 1900 1884 1901 /* 1902 * Send only if fits into the window, respecting the possible 1903 * overflow. 1904 */ 1885 // send only if fits into the window 1886 // respecting the possible overflow 1905 1887 if (!IS_IN_INTERVAL_OVERFLOW( 1906 1888 (uint32_t) socket_data->last_outgoing, … … 1927 1909 previous = copy; 1928 1910 packet = pq_next(packet); 1929 1930 /* Overflow occurred? */ 1911 // overflow occurred ? 1931 1912 if (!packet && 1932 1913 (socket_data->last_outgoing > socket_data->next_outgoing)) { 1933 1914 printf("gpts overflow\n"); 1934 / * Continue from the beginning */1915 // continue from the beginning 1935 1916 packet = socket_data->outgoing; 1936 1917 } … … 1941 1922 } 1942 1923 1943 packet_t tcp_send_prepare_packet(socket_core_ref socket, tcp_socket_data_ref 1944 socket_data, packet_t packet, size_t data_length, size_t sequence_number) 1924 packet_t 1925 tcp_send_prepare_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, 1926 packet_t packet, size_t data_length, size_t sequence_number) 1945 1927 { 1946 1928 tcp_header_ref header; … … 1952 1934 assert(socket->specific_data == socket_data); 1953 1935 1954 / * Adjust the pseudo header */1936 // adjust the pseudo header 1955 1937 rc = ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, 1956 1938 socket_data->headerlen, packet_get_data_length(packet)); … … 1960 1942 } 1961 1943 1962 / * Get the header */1944 // get the header 1963 1945 header = (tcp_header_ref) packet_get_data(packet); 1964 1946 if (!header) { … … 1968 1950 assert(ntohl(header->sequence_number) == sequence_number); 1969 1951 1970 / * Adjust the header */1952 // adjust the header 1971 1953 if (socket_data->next_incoming) { 1972 1954 header->acknowledgement_number = … … 1976 1958 header->window = htons(socket_data->window); 1977 1959 1978 / * Checksum */1960 // checksum 1979 1961 header->checksum = 0; 1980 1962 checksum = compute_checksum(0, socket_data->pseudo_header, … … 1985 1967 header->checksum = htons(flip_checksum(compact_checksum(checksum))); 1986 1968 1987 / * Prepare the packet */1969 // prepare the packet 1988 1970 rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0); 1989 1971 if (rc != EOK) { … … 1991 1973 return NULL; 1992 1974 } 1993 1994 1975 rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data, 1995 1976 sequence_number, socket_data->state, socket_data->timeout, true); … … 2002 1983 } 2003 1984 2004 packet_t tcp_prepare_copy(socket_core_ref socket, tcp_socket_data_ref 2005 socket_data, packet_t packet, size_t data_length, size_t sequence_number) 1985 packet_t 1986 tcp_prepare_copy(socket_core_ref socket, tcp_socket_data_ref socket_data, 1987 packet_t packet, size_t data_length, size_t sequence_number) 2006 1988 { 2007 1989 packet_t copy; … … 2011 1993 assert(socket->specific_data == socket_data); 2012 1994 2013 / * Make a copy of the packet */1995 // make a copy of the packet 2014 1996 copy = packet_get_copy(tcp_globals.net_phone, packet); 2015 1997 if (!copy) … … 2032 2014 } 2033 2015 2034 void tcp_prepare_operation_header(socket_core_ref socket, 2016 void 2017 tcp_prepare_operation_header(socket_core_ref socket, 2035 2018 tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, 2036 2019 int finalize) … … 2049 2032 } 2050 2033 2051 int tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t), 2034 int 2035 tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t), 2052 2036 socket_core_ref socket, tcp_socket_data_ref socket_data, 2053 2037 size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, … … 2061 2045 assert(socket->specific_data == socket_data); 2062 2046 2063 / * Prepare the timeout with key bundle structure */2047 // prepare the timeout with key bundle structure 2064 2048 operation_timeout = malloc(sizeof(*operation_timeout) + 2065 2049 socket->key_length + 1); … … 2076 2060 operation_timeout->state = state; 2077 2061 2078 / * Copy the key */2062 // copy the key 2079 2063 operation_timeout->key = ((char *) operation_timeout) + 2080 2064 sizeof(*operation_timeout); … … 2083 2067 operation_timeout->key[operation_timeout->key_length] = '\0'; 2084 2068 2085 / * Prepare the timeouting thread */2069 // prepare the timeouting thread 2086 2070 fibril = fibril_create(timeout_function, operation_timeout); 2087 2071 if (!fibril) { … … 2090 2074 } 2091 2075 // fibril_mutex_lock(&socket_data->operation.mutex); 2092 / * Start the timeout fibril */2076 // start the timeouting fibril 2093 2077 fibril_add_ready(fibril); 2094 2078 //socket_data->state = state; … … 2096 2080 } 2097 2081 2098 int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, 2099 int flags, size_t *addrlen) 2082 int 2083 tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, 2084 size_t *addrlen) 2100 2085 { 2101 2086 socket_core_ref socket; … … 2108 2093 assert(local_sockets); 2109 2094 2110 / * Find the socket */2095 // find the socket 2111 2096 socket = socket_cores_find(local_sockets, socket_id); 2112 2097 if (!socket) 2113 2098 return ENOTSOCK; 2114 2099 2115 / * Get the socket specific data */2100 // get the socket specific data 2116 2101 if (!socket->specific_data) 2117 2102 return NO_DATA; … … 2119 2104 socket_data = (tcp_socket_data_ref) socket->specific_data; 2120 2105 2121 / * Check state */2106 // check state 2122 2107 if ((socket_data->state != TCP_SOCKET_ESTABLISHED) && 2123 2108 (socket_data->state != TCP_SOCKET_CLOSE_WAIT)) 2124 2109 return ENOTCONN; 2125 2110 2126 / * Send the source address if desired */2111 // send the source address if desired 2127 2112 if (addrlen) { 2128 2113 rc = data_reply(socket_data->addr, socket_data->addrlen); … … 2132 2117 } 2133 2118 2134 / * Get the next received packet */2119 // get the next received packet 2135 2120 packet_id = dyn_fifo_value(&socket->received); 2136 2121 if (packet_id < 0) … … 2141 2126 return rc; 2142 2127 2143 / * Reply the packets */2128 // reply the packets 2144 2129 rc = socket_reply_packets(packet, &length); 2145 2130 if (rc != EOK) 2146 2131 return rc; 2147 2132 2148 / * Release the packet */2133 // release the packet 2149 2134 dyn_fifo_pop(&socket->received); 2150 2135 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 2151 2152 /* Return the total length */ 2136 // return the total length 2153 2137 return (int) length; 2154 2138 } 2155 2139 2156 int tcp_send_message(socket_cores_ref local_sockets, int socket_id, 2157 int fragments, size_t *data_fragment_size, int flags) 2140 int 2141 tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, 2142 size_t *data_fragment_size, int flags) 2158 2143 { 2159 2144 socket_core_ref socket; … … 2170 2155 assert(data_fragment_size); 2171 2156 2172 / * Find the socket */2157 // find the socket 2173 2158 socket = socket_cores_find(local_sockets, socket_id); 2174 2159 if (!socket) 2175 2160 return ENOTSOCK; 2176 2161 2177 / * Get the socket specific data */2162 // get the socket specific data 2178 2163 if (!socket->specific_data) 2179 2164 return NO_DATA; … … 2181 2166 socket_data = (tcp_socket_data_ref) socket->specific_data; 2182 2167 2183 / * Check state */2168 // check state 2184 2169 if ((socket_data->state != TCP_SOCKET_ESTABLISHED) && 2185 2170 (socket_data->state != TCP_SOCKET_CLOSE_WAIT)) … … 2196 2181 2197 2182 for (index = 0; index < fragments; index++) { 2198 / * Read the data fragment */2183 // read the data fragment 2199 2184 result = tl_socket_read_packet_data(tcp_globals.net_phone, 2200 2185 &packet, TCP_HEADER_SIZE, packet_dimension, … … 2204 2189 2205 2190 total_length = (size_t) result; 2206 2207 /* Prefix the TCP header */ 2191 // prefix the tcp header 2208 2192 header = PACKET_PREFIX(packet, tcp_header_t); 2209 2193 if (!header) … … 2216 2200 } 2217 2201 2218 / * Flush packets */2202 // flush packets 2219 2203 packet = tcp_get_packets_to_send(socket, socket_data); 2220 2204 fibril_rwlock_write_unlock(socket_data->local_lock); … … 2222 2206 2223 2207 if (packet) { 2224 / * Send the packet */2208 // send the packet 2225 2209 tcp_send_packets(socket_data->device_id, packet); 2226 2210 } … … 2237 2221 int rc; 2238 2222 2239 / * Find the socket */2223 // find the socket 2240 2224 socket = socket_cores_find(local_sockets, socket_id); 2241 2225 if (!socket) 2242 2226 return ENOTSOCK; 2243 2227 2244 / * Get the socket specific data */2228 // get the socket specific data 2245 2229 socket_data = (tcp_socket_data_ref) socket->specific_data; 2246 2230 assert(socket_data); 2247 2231 2248 / * Check state */2232 // check state 2249 2233 switch (socket_data->state) { 2250 2234 case TCP_SOCKET_ESTABLISHED: … … 2259 2243 2260 2244 default: 2261 / * Just destroy */2245 // just destroy 2262 2246 rc = socket_destroy(tcp_globals.net_phone, socket_id, 2263 2247 local_sockets, &tcp_globals.sockets, … … 2270 2254 } 2271 2255 2272 /* 2273 * Send FIN. 2274 * TODO should I wait to complete? 2275 */ 2276 2277 /* Create the notification packet */ 2256 // send FIN 2257 // TODO should I wait to complete? 2258 2259 // create the notification packet 2278 2260 rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1); 2279 2261 if (rc != EOK) 2280 2262 return rc; 2281 2263 2282 / * Send the packet */2264 // send the packet 2283 2265 rc = tcp_queue_packet(socket, socket_data, packet, 1); 2284 2266 if (rc != EOK) 2285 2267 return rc; 2286 2268 2287 / * Flush packets */2269 // flush packets 2288 2270 packet = tcp_get_packets_to_send(socket, socket_data); 2289 2271 fibril_rwlock_write_unlock(socket_data->local_lock); … … 2291 2273 2292 2274 if (packet) { 2293 / * Send the packet */2275 // send the packet 2294 2276 tcp_send_packets(socket_data->device_id, packet); 2295 2277 } … … 2298 2280 } 2299 2281 2300 int tcp_create_notification_packet(packet_t *packet, socket_core_ref socket, 2282 int 2283 tcp_create_notification_packet(packet_t *packet, socket_core_ref socket, 2301 2284 tcp_socket_data_ref socket_data, int synchronize, int finalize) 2302 2285 { … … 2307 2290 assert(packet); 2308 2291 2309 / * Get the device packet dimension */2292 // get the device packet dimension 2310 2293 rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone, 2311 2294 &tcp_globals.dimensions, socket_data->device_id, &packet_dimension); … … 2313 2296 return rc; 2314 2297 2315 / * Get a new packet */2298 // get a new packet 2316 2299 *packet = packet_get_4_remote(tcp_globals.net_phone, TCP_HEADER_SIZE, 2317 2300 packet_dimension->addr_len, packet_dimension->prefix, … … 2321 2304 return ENOMEM; 2322 2305 2323 / * Allocate space in the packet */2306 // allocate space in the packet 2324 2307 header = PACKET_SUFFIX(*packet, tcp_header_t); 2325 2308 if (!header) … … 2332 2315 } 2333 2316 2334 int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, 2317 int 2318 tcp_accept_message(socket_cores_ref local_sockets, int socket_id, 2335 2319 int new_socket_id, size_t *data_fragment_size, size_t *addrlen) 2336 2320 { … … 2345 2329 assert(addrlen); 2346 2330 2347 / * Find the socket */2331 // find the socket 2348 2332 socket = socket_cores_find(local_sockets, socket_id); 2349 2333 if (!socket) 2350 2334 return ENOTSOCK; 2351 2335 2352 / * Get the socket specific data */2336 // get the socket specific data 2353 2337 socket_data = (tcp_socket_data_ref) socket->specific_data; 2354 2338 assert(socket_data); 2355 2339 2356 / * Check state */2340 // check state 2357 2341 if (socket_data->state != TCP_SOCKET_LISTEN) 2358 2342 return EINVAL; … … 2368 2352 return ENOTSOCK; 2369 2353 2370 / * Get the socket specific data */2354 // get the socket specific data 2371 2355 socket_data = (tcp_socket_data_ref) accepted->specific_data; 2372 2356 assert(socket_data); 2373 / * TODO can it be in another state? */2357 // TODO can it be in another state? 2374 2358 if (socket_data->state == TCP_SOCKET_ESTABLISHED) { 2375 2359 rc = data_reply(socket_data->addr, … … 2405 2389 } 2406 2390 2407 void tcp_free_socket_data(socket_core_ref socket) 2391 void 2392 tcp_free_socket_data(socket_core_ref socket) 2408 2393 { 2409 2394 tcp_socket_data_ref socket_data; … … 2413 2398 printf("destroy_socket %d\n", socket->socket_id); 2414 2399 2415 / * Get the socket specific data */2400 // get the socket specific data 2416 2401 socket_data = (tcp_socket_data_ref) socket->specific_data; 2417 2402 assert(socket_data); 2418 2419 /* Free the pseudo header */ 2403 //free the pseudo header 2420 2404 if (socket_data->pseudo_header) { 2421 2405 if (socket_data->headerlen) { … … 2426 2410 socket_data->pseudo_header = NULL; 2427 2411 } 2428 2429 2412 socket_data->headerlen = 0; 2430 2431 /* Free the address */ 2413 // free the address 2432 2414 if (socket_data->addr) { 2433 2415 if (socket_data->addrlen) { … … 2491 2473 2492 2474 /* 2493 *Answer the message2475 Answer the message 2494 2476 */ 2495 2477 answer_call(callid, res, &answer, answer_count);
Note:
See TracChangeset
for help on using the changeset viewer.