Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/tcp/tcp.c

    r228e490 r86f6121  
    205205static int tcp_queue_received_packet(socket_core_t *, tcp_socket_data_t *,
    206206    packet_t *, int, size_t);
     207static void tcp_queue_received_end_of_data(socket_core_t *socket);
    207208
    208209static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t);
     
    453454
    454455has_error_service:
    455         fibril_rwlock_read_unlock(&tcp_globals.lock);
     456        fibril_rwlock_write_unlock(&tcp_globals.lock);
    456457
    457458        /* TODO error reporting/handling */
     
    504505        size_t offset;
    505506        uint32_t new_sequence_number;
     507        bool forced_ack;
    506508        int rc;
    507509
     
    512514        assert(packet);
    513515
     516        forced_ack = false;
     517
    514518        new_sequence_number = ntohl(header->sequence_number);
    515519        old_incoming = socket_data->next_incoming;
    516520
    517         if (header->finalize)
    518                 socket_data->fin_incoming = new_sequence_number;
     521        if (header->finalize) {
     522                socket_data->fin_incoming = new_sequence_number +
     523                    total_length - TCP_HEADER_LENGTH(header);
     524        }
    519525
    520526        /* Trim begining if containing expected data */
     
    760766                /* Release duplicite or restricted */
    761767                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)) {
     768                forced_ack = true;
     769        }
     770
     771        /* If next in sequence is an incoming FIN */
     772        if (socket_data->next_incoming == socket_data->fin_incoming) {
     773                /* Advance sequence number */
     774                socket_data->next_incoming += 1;
     775
     776                /* Handle FIN */
    767777                switch (socket_data->state) {
    768778                case TCP_SOCKET_FIN_WAIT_1:
     
    771781                        socket_data->state = TCP_SOCKET_CLOSING;
    772782                        break;
    773                 /*case TCP_ESTABLISHED:*/
     783                case TCP_SOCKET_ESTABLISHED:
     784                        /* Queue end-of-data marker on the socket. */
     785                        tcp_queue_received_end_of_data(socket);
     786                        socket_data->state = TCP_SOCKET_CLOSE_WAIT;
     787                        break;
    774788                default:
    775789                        socket_data->state = TCP_SOCKET_CLOSE_WAIT;
     
    779793
    780794        packet = tcp_get_packets_to_send(socket, socket_data);
    781         if (!packet) {
     795        if (!packet && (socket_data->next_incoming != old_incoming || forced_ack)) {
    782796                /* Create the notification packet */
    783797                rc = tcp_create_notification_packet(&packet, socket,
     
    835849
    836850        return EOK;
     851}
     852
     853/** Queue end-of-data marker on the socket.
     854 *
     855 * Next element in the sequence space is FIN. Queue end-of-data marker
     856 * on the socket.
     857 *
     858 * @param socket        Socket
     859 */
     860static void tcp_queue_received_end_of_data(socket_core_t *socket)
     861{
     862        assert(socket != NULL);
     863
     864        /* Notify the destination socket */
     865        async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
     866            (sysarg_t) socket->socket_id,
     867            0, 0, 0,
     868            (sysarg_t) 0 /* 0 fragments == no more data */);
    837869}
    838870
     
    13651397
    13661398                case NET_SOCKET_BIND:
    1367                         res = data_receive((void **) &addr, &addrlen);
     1399                        res = async_data_write_accept((void **) &addr, false,
     1400                            0, 0, 0, &addrlen);
    13681401                        if (res != EOK)
    13691402                                break;
     
    14021435
    14031436                case NET_SOCKET_CONNECT:
    1404                         res = data_receive((void **) &addr, &addrlen);
     1437                        res = async_data_write_accept((void **) &addr, false,
     1438                            0, 0, 0, &addrlen);
    14051439                        if (res != EOK)
    14061440                                break;
     
    14531487
    14541488                case NET_SOCKET_SENDTO:
    1455                         res = data_receive((void **) &addr, &addrlen);
     1489                        res = async_data_write_accept((void **) &addr, false,
     1490                            0, 0, 0, &addrlen);
    14561491                        if (res != EOK)
    14571492                                break;
     
    18001835                        fibril_rwlock_write_unlock(socket_data->local_lock);
    18011836
     1837                        socket_data->state = TCP_SOCKET_SYN_SENT;
     1838
    18021839                        /* Send the packet */
    18031840                        printf("connecting %d\n", packet_get_id(packet));
     
    20822119        if (!fibril) {
    20832120                free(operation_timeout);
    2084                 return EPARTY;  /* FIXME: use another EC */
    2085         }
     2121                return ENOMEM;
     2122        }
     2123
    20862124//      fibril_mutex_lock(&socket_data->operation.mutex);
    20872125        /* Start the timeout fibril */
     
    22062244
    22072245                tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
    2208                 rc = tcp_queue_packet(socket, socket_data, packet, 0);
     2246                rc = tcp_queue_packet(socket, socket_data, packet, total_length);
    22092247                if (rc != EOK)
    22102248                        return rc;
Note: See TracChangeset for help on using the changeset viewer.