Ignore:
File:
1 edited

Legend:

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

    r472020fc r89e57cee  
    2828
    2929/** @addtogroup tcp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  TCP module implementation.
    35  *  @see tcp.h
     34 * TCP module implementation.
     35 * @see tcp.h
    3636 */
     37
     38#include "tcp.h"
     39#include "tcp_header.h"
     40#include "tcp_module.h"
    3741
    3842#include <assert.h>
     
    7276#include <tl_interface.h>
    7377
    74 #include "tcp.h"
    75 #include "tcp_header.h"
    76 #include "tcp_module.h"
    77 
    7878/** TCP module name. */
    7979#define NAME    "TCP protocol"
     
    110110
    111111/** Returns a value indicating whether the value is in the interval respecting
    112  *  the possible overflow.
     112 * the possible overflow.
    113113 *
    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.
    118119 */
    119120#define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \
     
    165166};
    166167
    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);
     168static int tcp_release_and_return(packet_t, int);
     169static void tcp_prepare_operation_header(socket_core_ref, tcp_socket_data_ref,
     170    tcp_header_ref, int synchronize, int);
     171static int tcp_prepare_timeout(int (*)(void *), socket_core_ref,
     172    tcp_socket_data_ref, size_t, tcp_socket_state_t, suseconds_t, int);
     173static void tcp_free_socket_data(socket_core_ref);
     174
     175static int tcp_timeout(void *);
     176
     177static int tcp_release_after_timeout(void *);
     178
     179static int tcp_process_packet(device_id_t, packet_t, services_t);
     180static int tcp_connect_core(socket_core_ref, socket_cores_ref,
     181    struct sockaddr *, socklen_t);
     182static int tcp_queue_prepare_packet(socket_core_ref, tcp_socket_data_ref,
     183    packet_t, size_t);
     184static int tcp_queue_packet(socket_core_ref, tcp_socket_data_ref, packet_t,
     185    size_t);
     186static packet_t tcp_get_packets_to_send(socket_core_ref, tcp_socket_data_ref);
     187static void tcp_send_packets(device_id_t, packet_t);
     188
     189static void tcp_process_acknowledgement(socket_core_ref, tcp_socket_data_ref,
     190    tcp_header_ref);
     191static packet_t tcp_send_prepare_packet(socket_core_ref, tcp_socket_data_ref,
     192    packet_t, size_t, size_t);
     193static 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);
     197static int tcp_create_notification_packet(packet_t *, socket_core_ref,
     198    tcp_socket_data_ref, int, int);
     199static void tcp_refresh_socket_data(tcp_socket_data_ref);
     200
     201static void tcp_initialize_socket_data(tcp_socket_data_ref);
     202
     203static int tcp_process_listen(socket_core_ref, tcp_socket_data_ref,
     204    tcp_header_ref, packet_t, struct sockaddr *, struct sockaddr *, size_t);
     205static int tcp_process_syn_sent(socket_core_ref, tcp_socket_data_ref,
     206    tcp_header_ref, packet_t);
     207static int tcp_process_syn_received(socket_core_ref, tcp_socket_data_ref,
     208    tcp_header_ref, packet_t);
     209static int tcp_process_established(socket_core_ref, tcp_socket_data_ref,
     210    tcp_header_ref, packet_t, int, size_t);
     211static int tcp_queue_received_packet(socket_core_ref, tcp_socket_data_ref,
     212    packet_t, int, size_t);
     213
     214static int tcp_received_msg(device_id_t, packet_t, services_t, services_t);
     215static int tcp_process_client_messages(ipc_callid_t, ipc_call_t);
     216
     217static int tcp_listen_message(socket_cores_ref, int, int);
     218static int tcp_connect_message(socket_cores_ref, int, struct sockaddr *,
     219    socklen_t);
     220static int tcp_recvfrom_message(socket_cores_ref, int, int, size_t *);
     221static int tcp_send_message(socket_cores_ref, int, int, size_t *, int);
     222static int tcp_accept_message(socket_cores_ref, int, int, size_t *, size_t *);
     223static int tcp_close_message(socket_cores_ref, int);
    245224
    246225/** TCP global data. */
    247226tcp_globals_t tcp_globals;
    248227
     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 */
    249235int tcp_initialize(async_client_conn_t client_connection)
    250236{
     
    314300        size_t addrlen;
    315301
    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);
    335318        }
    336319
     
    379362                    ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING,
    380363                    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                                     0, packet);
    387                         }
    388                         return EADDRNOTAVAIL;
    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
    391374        printf("socket id %d\n", socket->socket_id);
    392375        socket_data = (tcp_socket_data_ref) socket->specific_data;
     
    402385        total_length = 0;
    403386        do {
    404                 ++fragments;
     387                fragments++;
    405388                length = packet_get_data_length(next_packet);
    406389                if (length <= 0)
     
    421404
    422405        if (error)
    423                 goto error;
     406                goto has_error_service;
    424407       
    425408        if (socket_data->state == TCP_SOCKET_LISTEN) {
    426 
    427409                if (socket_data->pseudo_header) {
    428410                        free(socket_data->pseudo_header);
     
    464446        }
    465447
    466 error:
     448has_error_service:
    467449        fibril_rwlock_read_unlock(&tcp_globals.lock);
    468450
     
    507489int
    508490tcp_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)
    511492{
    512493        ERROR_DECLARE;
     
    684665                                        continue;
    685666                                        // 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)) {
    689670                                        if (socket_data->next_incoming <
    690671                                            new_sequence_number) {
     
    961942        listening_socket = socket_port_find(&tcp_globals.sockets,
    962943            listening_port, SOCKET_MAP_KEY_LISTENING, 0);
    963         if ((!listening_socket) ||
     944        if (!listening_socket ||
    964945            (listening_socket->socket_id != listening_socket_id)) {
    965946                fibril_rwlock_write_unlock(&tcp_globals.lock);
     
    11911172        if (number == socket_data->expected) {
    11921173                // increase the counter
    1193                 ++socket_data->expected_count;
     1174                socket_data->expected_count++;
    11941175                if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) {
    11951176                        socket_data->expected_count = 1;
     
    12001181}
    12011182
    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 */
     1196int
     1197tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     1198    ipc_call_t *answer, int *answer_count)
    12041199{
    12051200        ERROR_DECLARE;
     
    15211516        socket = socket_port_find(&tcp_globals.sockets, timeout->port,
    15221517            timeout->key, timeout->key_length);
    1523         if (!(socket && (socket->socket_id == timeout->socket_id)))
     1518        if (!socket || (socket->socket_id != timeout->socket_id))
    15241519                goto out;
    15251520       
     
    15321527        if (timeout->sequence_number) {
    15331528                // increase the timeout counter;
    1534                 ++socket_data->timeout_count;
     1529                socket_data->timeout_count++;
    15351530                if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) {
    15361531                        // TODO release as connection lost
     
    17441739            ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data,
    17451740            0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))) {
    1746 
    17471741                socket_data->addr = NULL;
    17481742                socket_data->addrlen = 0;
    17491743                fibril_rwlock_write_lock(&tcp_globals.lock);
    1750 
    17511744        } else {
    1752 
    17531745                packet = tcp_get_packets_to_send(socket, socket_data);
    17541746                if (packet) {
     
    18761868                packet = pq_next(packet);
    18771869                // overflow occurred ?
    1878                 if ((!packet) &&
     1870                if (!packet &&
    18791871                    (socket_data->last_outgoing > socket_data->next_outgoing)) {
    18801872                        printf("gpts overflow\n");
     
    20442036int
    20452037tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
    2046     size_t * addrlen)
     2038    size_t *addrlen)
    20472039{
    20482040        ERROR_DECLARE;
     
    20992091int
    21002092tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments,
    2101     size_t * data_fragment_size, int flags)
     2093    size_t *data_fragment_size, int flags)
    21022094{
    21032095        ERROR_DECLARE;
     
    21382130            packet_dimension->content : socket_data->data_fragment_size);
    21392131
    2140         for (index = 0; index < fragments; ++index) {
     2132        for (index = 0; index < fragments; index++) {
    21412133                // read the data fragment
    21422134                result = tl_socket_read_packet_data(tcp_globals.net_phone,
     
    22352227
    22362228int
    2237 tcp_create_notification_packet(packet_t * packet, socket_core_ref socket,
     2229tcp_create_notification_packet(packet_t *packet, socket_core_ref socket,
    22382230    tcp_socket_data_ref socket_data, int synchronize, int finalize)
    22392231{
     
    22712263int
    22722264tcp_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)
    22742266{
    22752267        ERROR_DECLARE;
     
    23732365}
    23742366
     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 */
    23752373int tcp_release_and_return(packet_t packet, int result)
    23762374{
     
    23812379/** Default thread for new connections.
    23822380 *
    2383  *  @param[in] iid The initial message identifier.
    2384  *  @param[in] icall The initial message call structure.
     2381 * @param[in] iid       The initial message identifier.
     2382 * @param[in] icall     The initial message call structure.
    23852383 *
    23862384 */
     
    23972395                int answer_count;
    23982396
    2399                 /*
    2400                    Clear the answer structure
    2401                  */
     2397                /* Clear the answer structure */
    24022398                refresh_answer(&answer, &answer_count);
    24032399
    2404                 /*
    2405                    Fetch the next message
    2406                  */
     2400                /* Fetch the next message */
    24072401                ipc_call_t call;
    24082402                ipc_callid_t callid = async_get_call(&call);
    24092403
    2410                 /*
    2411                    Process the message
    2412                  */
     2404                /* Process the message */
    24132405                int res = tl_module_message_standalone(callid, &call, &answer,
    24142406                    &answer_count);
    24152407
    24162408                /*
    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.
    24182411                 */
    24192412                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     
    24302423/** Starts the module.
    24312424 *
    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.
    24382428 */
    24392429int
Note: See TracChangeset for help on using the changeset viewer.