Changeset 357b5f5 in mainline for uspace/srv/net/tl/tcp/tcp.c


Ignore:
Timestamp:
2011-01-23T20:09:13Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fdb9982c
Parents:
cead2aa (diff), 7e36c8d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    rcead2aa r357b5f5  
    3636 */
    3737
    38 #include "tcp.h"
    39 #include "tcp_header.h"
    40 #include "tcp_module.h"
    41 
    4238#include <assert.h>
    4339#include <async.h>
     
    6864#include <ip_interface.h>
    6965#include <icmp_client.h>
    70 #include <icmp_interface.h>
     66#include <icmp_remote.h>
    7167#include <net_interface.h>
    7268#include <socket_core.h>
    7369#include <tl_common.h>
    74 #include <tl_local.h>
    75 #include <tl_interface.h>
     70#include <tl_remote.h>
     71#include <tl_skel.h>
     72
     73#include "tcp.h"
     74#include "tcp_header.h"
    7675
    7776/** TCP module name. */
    78 #define NAME    "TCP protocol"
     77#define NAME  "tcp"
    7978
    8079/** The TCP window default value. */
     
    154153
    155154        /** Port map key. */
    156         char *key;
     155        uint8_t *key;
    157156
    158157        /** Port map key length. */
     
    205204static int tcp_queue_received_packet(socket_core_t *, tcp_socket_data_t *,
    206205    packet_t *, int, size_t);
     206static void tcp_queue_received_end_of_data(socket_core_t *socket);
    207207
    208208static int tcp_received_msg(device_id_t, packet_t *, services_t, services_t);
     
    219219/** TCP global data. */
    220220tcp_globals_t tcp_globals;
    221 
    222 /** Initializes the TCP module.
    223  *
    224  * @param[in] client_connection The client connection processing function. The
    225  *                      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 }
    263221
    264222int tcp_received_msg(device_id_t device_id, packet_t *packet,
     
    357315        /* Find the destination socket */
    358316        socket = socket_port_find(&tcp_globals.sockets,
    359             ntohs(header->destination_port), (const char *) src, addrlen);
     317            ntohs(header->destination_port), (uint8_t *) src, addrlen);
    360318        if (!socket) {
    361319                /* Find the listening destination socket */
    362320                socket = socket_port_find(&tcp_globals.sockets,
    363                     ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING,
    364                     0);
     321                    ntohs(header->destination_port),
     322                    (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
    365323        }
    366324
     
    453411
    454412has_error_service:
    455         fibril_rwlock_read_unlock(&tcp_globals.lock);
     413        fibril_rwlock_write_unlock(&tcp_globals.lock);
    456414
    457415        /* TODO error reporting/handling */
     
    504462        size_t offset;
    505463        uint32_t new_sequence_number;
     464        bool forced_ack;
    506465        int rc;
    507466
     
    512471        assert(packet);
    513472
     473        forced_ack = false;
     474
    514475        new_sequence_number = ntohl(header->sequence_number);
    515476        old_incoming = socket_data->next_incoming;
    516477
    517         if (header->finalize)
    518                 socket_data->fin_incoming = new_sequence_number;
     478        if (header->finalize) {
     479                socket_data->fin_incoming = new_sequence_number +
     480                    total_length - TCP_HEADER_LENGTH(header);
     481        }
    519482
    520483        /* Trim begining if containing expected data */
     
    760723                /* Release duplicite or restricted */
    761724                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)) {
     725                forced_ack = true;
     726        }
     727
     728        /* If next in sequence is an incoming FIN */
     729        if (socket_data->next_incoming == socket_data->fin_incoming) {
     730                /* Advance sequence number */
     731                socket_data->next_incoming += 1;
     732
     733                /* Handle FIN */
    767734                switch (socket_data->state) {
    768735                case TCP_SOCKET_FIN_WAIT_1:
     
    771738                        socket_data->state = TCP_SOCKET_CLOSING;
    772739                        break;
    773                 /*case TCP_ESTABLISHED:*/
     740                case TCP_SOCKET_ESTABLISHED:
     741                        /* Queue end-of-data marker on the socket. */
     742                        tcp_queue_received_end_of_data(socket);
     743                        socket_data->state = TCP_SOCKET_CLOSE_WAIT;
     744                        break;
    774745                default:
    775746                        socket_data->state = TCP_SOCKET_CLOSE_WAIT;
     
    779750
    780751        packet = tcp_get_packets_to_send(socket, socket_data);
    781         if (!packet) {
     752        if (!packet && (socket_data->next_incoming != old_incoming || forced_ack)) {
    782753                /* Create the notification packet */
    783754                rc = tcp_create_notification_packet(&packet, socket,
     
    829800        /* Notify the destination socket */
    830801        async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
    831             (ipcarg_t) socket->socket_id,
     802            (sysarg_t) socket->socket_id,
    832803            ((packet_dimension->content < socket_data->data_fragment_size) ?
    833804            packet_dimension->content : socket_data->data_fragment_size), 0, 0,
    834             (ipcarg_t) fragments);
     805            (sysarg_t) fragments);
    835806
    836807        return EOK;
     808}
     809
     810/** Queue end-of-data marker on the socket.
     811 *
     812 * Next element in the sequence space is FIN. Queue end-of-data marker
     813 * on the socket.
     814 *
     815 * @param socket        Socket
     816 */
     817static void tcp_queue_received_end_of_data(socket_core_t *socket)
     818{
     819        assert(socket != NULL);
     820
     821        /* Notify the destination socket */
     822        async_msg_5(socket->phone, NET_SOCKET_RECEIVED,
     823            (sysarg_t) socket->socket_id,
     824            0, 0, 0,
     825            (sysarg_t) 0 /* 0 fragments == no more data */);
    837826}
    838827
     
    966955        /* Find the destination socket */
    967956        listening_socket = socket_port_find(&tcp_globals.sockets,
    968             listening_port, SOCKET_MAP_KEY_LISTENING, 0);
     957            listening_port, (uint8_t *) SOCKET_MAP_KEY_LISTENING, 0);
    969958        if (!listening_socket ||
    970959            (listening_socket->socket_id != listening_socket_id)) {
     
    990979
    991980        rc = socket_port_add(&tcp_globals.sockets, listening_port, socket,
    992             (const char *) socket_data->addr, socket_data->addrlen);
     981            (uint8_t *) socket_data->addr, socket_data->addrlen);
    993982        assert(socket == socket_port_find(&tcp_globals.sockets, listening_port,
    994             (const char *) socket_data->addr, socket_data->addrlen));
     983            (uint8_t *) socket_data->addr, socket_data->addrlen));
    995984
    996985//      rc = socket_bind_free_port(&tcp_globals.sockets, socket,
     
    10901079                        /* Notify the destination socket */
    10911080                        async_msg_5(socket->phone, NET_SOCKET_ACCEPTED,
    1092                             (ipcarg_t) listening_socket->socket_id,
     1081                            (sysarg_t) listening_socket->socket_id,
    10931082                            socket_data->data_fragment_size, TCP_HEADER_SIZE,
    1094                             0, (ipcarg_t) socket->socket_id);
     1083                            0, (sysarg_t) socket->socket_id);
    10951084
    10961085                        fibril_rwlock_write_unlock(socket_data->local_lock);
     
    12151204}
    12161205
     1206/** Per-connection initialization
     1207 *
     1208 */
     1209void tl_connection(void)
     1210{
     1211}
     1212
    12171213/** Processes the TCP message.
    12181214 *
     
    12281224 * @see IS_NET_TCP_MESSAGE()
    12291225 */
    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 
     1226int tl_message(ipc_callid_t callid, ipc_call_t *call,
     1227    ipc_call_t *answer, size_t *answer_count)
     1228{
    12371229        assert(call);
    12381230        assert(answer);
     
    12401232
    12411233        *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;
     1234        switch (IPC_GET_IMETHOD(*call)) {
    12551235        case IPC_M_CONNECT_TO_ME:
    12561236                return tcp_process_client_messages(callid, *call);
     
    12911271        bool keep_on_going = true;
    12921272        socket_cores_t local_sockets;
    1293         int app_phone = IPC_GET_PHONE(&call);
     1273        int app_phone = IPC_GET_PHONE(call);
    12941274        struct sockaddr *addr;
    12951275        int socket_id;
     
    12981278        fibril_rwlock_t lock;
    12991279        ipc_call_t answer;
    1300         int answer_count;
     1280        size_t answer_count;
    13011281        tcp_socket_data_t *socket_data;
    13021282        socket_core_t *socket;
     
    13231303
    13241304                /* Process the call */
    1325                 switch (IPC_GET_METHOD(call)) {
     1305                switch (IPC_GET_IMETHOD(call)) {
    13261306                case IPC_M_PHONE_HUNGUP:
    13271307                        keep_on_going = false;
     
    13651345
    13661346                case NET_SOCKET_BIND:
    1367                         res = data_receive((void **) &addr, &addrlen);
     1347                        res = async_data_write_accept((void **) &addr, false,
     1348                            0, 0, 0, &addrlen);
    13681349                        if (res != EOK)
    13691350                                break;
     
    14021383
    14031384                case NET_SOCKET_CONNECT:
    1404                         res = data_receive((void **) &addr, &addrlen);
     1385                        res = async_data_write_accept((void **) &addr, false,
     1386                            0, 0, 0, &addrlen);
    14051387                        if (res != EOK)
    14061388                                break;
     
    14531435
    14541436                case NET_SOCKET_SENDTO:
    1455                         res = data_receive((void **) &addr, &addrlen);
     1437                        res = async_data_write_accept((void **) &addr, false,
     1438                            0, 0, 0, &addrlen);
    14561439                        if (res != EOK)
    14571440                                break;
     
    18001783                        fibril_rwlock_write_unlock(socket_data->local_lock);
    18011784
     1785                        socket_data->state = TCP_SOCKET_SYN_SENT;
     1786
    18021787                        /* Send the packet */
    18031788                        printf("connecting %d\n", packet_get_id(packet));
     
    20722057
    20732058        /* Copy the key */
    2074         operation_timeout->key = ((char *) operation_timeout) +
     2059        operation_timeout->key = ((uint8_t *) operation_timeout) +
    20752060            sizeof(*operation_timeout);
    20762061        operation_timeout->key_length = socket->key_length;
     
    20822067        if (!fibril) {
    20832068                free(operation_timeout);
    2084                 return EPARTY;  /* FIXME: use another EC */
    2085         }
     2069                return ENOMEM;
     2070        }
     2071
    20862072//      fibril_mutex_lock(&socket_data->operation.mutex);
    20872073        /* Start the timeout fibril */
     
    22062192
    22072193                tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
    2208                 rc = tcp_queue_packet(socket, socket_data, packet, 0);
     2194                rc = tcp_queue_packet(socket, socket_data, packet, total_length);
    22092195                if (rc != EOK)
    22102196                        return rc;
     
    24482434}
    24492435
    2450 /** Default thread for new connections.
     2436/** Process IPC messages from the IP module
    24512437 *
    2452  * @param[in] iid       The initial message identifier.
    2453  * @param[in] icall     The initial message call structure.
     2438 * @param[in]     iid   Message identifier.
     2439 * @param[in,out] icall Message parameters.
    24542440 *
    24552441 */
    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 
     2442static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall)
     2443{
     2444        packet_t *packet;
     2445        int rc;
     2446       
    24642447        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.
     2448                switch (IPC_GET_IMETHOD(*icall)) {
     2449                case NET_TL_RECEIVED:
     2450                        rc = packet_translate_remote(tcp_globals.net_phone, &packet,
     2451                            IPC_GET_PACKET(*icall));
     2452                        if (rc == EOK)
     2453                                rc = tcp_received_msg(IPC_GET_DEVICE(*icall), packet,
     2454                                    SERVICE_TCP, IPC_GET_ERROR(*icall));
     2455                       
     2456                        ipc_answer_0(iid, (sysarg_t) rc);
     2457                        break;
     2458                default:
     2459                        ipc_answer_0(iid, (sysarg_t) ENOTSUP);
     2460                }
     2461               
     2462                iid = async_get_call(icall);
     2463        }
     2464}
     2465
     2466/** Initialize the TCP module.
    24952467 *
    2496  * @return              EOK on success.
    2497  * @return              Other error codes as defined for each specific module
    2498  *                      start function.
     2468 * @param[in] net_phone Network module phone.
     2469 *
     2470 * @return EOK on success.
     2471 * @return ENOMEM if there is not enough memory left.
     2472 *
    24992473 */
    2500 int
    2501 main(int argc, char *argv[])
    2502 {
    2503         int rc;
    2504 
    2505         rc = tl_module_start_standalone(tl_client_connection);
     2474int tl_initialize(int net_phone)
     2475{
     2476        fibril_rwlock_initialize(&tcp_globals.lock);
     2477        fibril_rwlock_write_lock(&tcp_globals.lock);
     2478       
     2479        tcp_globals.net_phone = net_phone;
     2480       
     2481        tcp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT);
     2482        tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
     2483            SERVICE_TCP, tcp_receiver);
     2484        if (tcp_globals.ip_phone < 0) {
     2485                fibril_rwlock_write_unlock(&tcp_globals.lock);
     2486                return tcp_globals.ip_phone;
     2487        }
     2488       
     2489        int rc = socket_ports_initialize(&tcp_globals.sockets);
     2490        if (rc != EOK)
     2491                goto out;
     2492
     2493        rc = packet_dimensions_initialize(&tcp_globals.dimensions);
     2494        if (rc != EOK) {
     2495                socket_ports_destroy(&tcp_globals.sockets);
     2496                goto out;
     2497        }
     2498
     2499        tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
     2500
     2501out:
     2502        fibril_rwlock_write_unlock(&tcp_globals.lock);
    25062503        return rc;
     2504}
     2505
     2506int main(int argc, char *argv[])
     2507{
     2508        return tl_module_start(SERVICE_TCP);
    25072509}
    25082510
Note: See TracChangeset for help on using the changeset viewer.