Changeset 97c7682 in mainline for uspace/srv/net/tcp/sock.c


Ignore:
Timestamp:
2012-07-14T11:18:40Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
804d9b6
Parents:
0747468 (diff), f0348c8 (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.

Text conflict in boot/arch/arm32/Makefile.inc:

Trivial conflict around ifeq condition.

Text conflict in kernel/arch/arm32/include/mm/page.h:

Added defines and set_pt_levelx_present function.
COnflict looked horrible because of the armv4/v7 split.

File:
1 moved

Legend:

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

    r0747468 r97c7682  
    3838#include <async.h>
    3939#include <errno.h>
     40#include <inet/inet.h>
    4041#include <io/log.h>
    41 #include <ip_client.h>
     42#include <ipc/services.h>
    4243#include <ipc/socket.h>
    43 #include <net/modules.h>
    4444#include <net/socket.h>
     45#include <ns.h>
    4546
    4647#include "sock.h"
     
    5051#include "ucall.h"
    5152
    52 #define FRAGMENT_SIZE 1024
    53 
    5453#define MAX_BACKLOG 128
    5554
     
    6362static socket_ports_t gsock;
    6463
     64static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    6565static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg);
    66 
    67 void tcp_sock_init(void)
     66static int tcp_sock_recv_fibril(void *arg);
     67
     68int tcp_sock_init(void)
    6869{
    6970        socket_ports_initialize(&gsock);
     71       
     72        async_set_client_connection(tcp_sock_connection);
     73       
     74        int rc = service_register(SERVICE_TCP);
     75        if (rc != EOK)
     76                return EEXIST;
     77       
     78        return EOK;
    7079}
    7180
     
    7685        socket = (tcp_sockdata_t *)sock_core->specific_data;
    7786        (void)socket;
     87
     88        /* XXX We need to initiate connection cleanup here */
    7889}
    7990
     
    8394        async_exch_t *exch = async_exchange_begin(sock_core->sess);
    8495        async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
    85             FRAGMENT_SIZE, 0, 0, 1);
     96            TCP_SOCK_FRAGMENT_SIZE, 0, 0, 1);
    8697        async_exchange_end(exch);
    8798}
     
    92103        async_exch_t *exch = async_exchange_begin(lsock_core->sess);
    93104        async_msg_5(exch, NET_SOCKET_ACCEPTED, (sysarg_t)lsock_core->socket_id,
    94             FRAGMENT_SIZE, 0, 0, 0);
     105            TCP_SOCK_FRAGMENT_SIZE, 0, 0, 0);
    95106        async_exchange_end(exch);
    96107}
    97108
     109static int tcp_sock_create(tcp_client_t *client, tcp_sockdata_t **rsock)
     110{
     111        tcp_sockdata_t *sock;
     112
     113        log_msg(LVL_DEBUG, "tcp_sock_create()");
     114        *rsock = NULL;
     115
     116        sock = calloc(sizeof(tcp_sockdata_t), 1);
     117        if (sock == NULL)
     118                return ENOMEM;
     119
     120        fibril_mutex_initialize(&sock->lock);
     121        sock->client = client;
     122
     123        sock->recv_buffer_used = 0;
     124        sock->recv_error = TCP_EOK;
     125        fibril_mutex_initialize(&sock->recv_buffer_lock);
     126        fibril_condvar_initialize(&sock->recv_buffer_cv);
     127        list_initialize(&sock->ready);
     128
     129        *rsock = sock;
     130        return EOK;
     131}
     132
     133static void tcp_sock_uncreate(tcp_sockdata_t *sock)
     134{
     135        log_msg(LVL_DEBUG, "tcp_sock_uncreate()");
     136        free(sock);
     137}
     138
     139static int tcp_sock_finish_setup(tcp_sockdata_t *sock, int *sock_id)
     140{
     141        socket_core_t *sock_core;
     142        int rc;
     143
     144        log_msg(LVL_DEBUG, "tcp_sock_finish_setup()");
     145
     146        sock->recv_fibril = fibril_create(tcp_sock_recv_fibril, sock);
     147        if (sock->recv_fibril == 0)
     148                return ENOMEM;
     149
     150        rc = socket_create(&sock->client->sockets, sock->client->sess,
     151            sock, sock_id);
     152
     153        if (rc != EOK) {
     154                fibril_destroy(sock->recv_fibril);
     155                sock->recv_fibril = 0;
     156                return rc;
     157        }
     158
     159        sock_core = socket_cores_find(&sock->client->sockets, *sock_id);
     160        assert(sock_core != NULL);
     161        sock->sock_core = sock_core;
     162
     163        return EOK;
     164}
     165
    98166static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    99167{
    100168        tcp_sockdata_t *sock;
    101         socket_core_t *sock_core;
    102169        int sock_id;
    103170        int rc;
     
    105172
    106173        log_msg(LVL_DEBUG, "tcp_sock_socket()");
    107         sock = calloc(sizeof(tcp_sockdata_t), 1);
    108         if (sock == NULL) {
    109                 async_answer_0(callid, ENOMEM);
    110                 return;
    111         }
    112 
    113         fibril_mutex_initialize(&sock->lock);
    114         sock->client = client;
     174
     175        rc = tcp_sock_create(client, &sock);
     176        if (rc != EOK) {
     177                async_answer_0(callid, rc);
     178                return;
     179        }
     180
    115181        sock->laddr.ipv4 = TCP_IPV4_ANY;
    116182        sock->lconn = NULL;
    117183        sock->backlog = 0;
    118         list_initialize(&sock->ready);
    119184
    120185        sock_id = SOCKET_GET_SOCKET_ID(call);
    121         rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
     186        rc = tcp_sock_finish_setup(sock, &sock_id);
    122187        if (rc != EOK) {
     188                tcp_sock_uncreate(sock);
    123189                async_answer_0(callid, rc);
    124190                return;
    125191        }
    126192
    127         sock_core = socket_cores_find(&client->sockets, sock_id);
    128         assert(sock_core != NULL);
    129         sock->sock_core = sock_core;
    130 
    131         refresh_answer(&answer, NULL);
    132193        SOCKET_SET_SOCKET_ID(answer, sock_id);
    133194
    134         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
     195        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
    135196        SOCKET_SET_HEADER_SIZE(answer, sizeof(tcp_header_t));
    136         answer_call(callid, EOK, &answer, 3);
     197       
     198        async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
     199            IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
    137200}
    138201
     
    273336        tcp_sock_t lsocket;
    274337        tcp_sock_t fsocket;
    275         nic_device_id_t dev_id;
    276         tcp_phdr_t *phdr;
    277         size_t phdr_len;
    278338
    279339        log_msg(LVL_DEBUG, "tcp_sock_connect()");
     
    309369
    310370        if (socket->laddr.ipv4 == TCP_IPV4_ANY) {
    311                 /* Find route to determine local IP address. */
    312                 rc = ip_get_route_req(ip_sess, IPPROTO_TCP,
    313                     (struct sockaddr *)addr, sizeof(*addr), &dev_id,
    314                     (void **)&phdr, &phdr_len);
     371                /* Determine local IP address */
     372                inet_addr_t loc_addr, rem_addr;
     373
     374                rem_addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
     375                rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
    315376                if (rc != EOK) {
    316377                        fibril_mutex_unlock(&socket->lock);
    317378                        async_answer_0(callid, rc);
    318                         log_msg(LVL_DEBUG, "tcp_transmit_connect: Failed to find route.");
     379                        log_msg(LVL_DEBUG, "tcp_sock_connect: Failed to "
     380                            "determine local address.");
    319381                        return;
    320382                }
    321383
    322                 socket->laddr.ipv4 = uint32_t_be2host(phdr->src_addr);
     384                socket->laddr.ipv4 = loc_addr.ipv4;
    323385                log_msg(LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4);
    324                 free(phdr);
    325386        }
    326387
     
    348409        }
    349410
     411        if (rc == EOK)
     412                fibril_add_ready(socket->recv_fibril);
     413
    350414        async_answer_0(callid, rc);
    351 
    352         /* Push one fragment notification to client's queue */
    353         tcp_sock_notify_data(sock_core);
    354         log_msg(LVL_DEBUG, "tcp_sock_connect(): notify conn\n");
    355415}
    356416
     
    361421        int asock_id;
    362422        socket_core_t *sock_core;
    363         socket_core_t *asock_core;
    364423        tcp_sockdata_t *socket;
    365424        tcp_sockdata_t *asocket;
     
    431490        /* Allocate socket for accepted connection */
    432491
    433         log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n");
    434         asocket = calloc(sizeof(tcp_sockdata_t), 1);
    435         if (asocket == NULL) {
    436                 fibril_mutex_unlock(&socket->lock);
    437                 async_answer_0(callid, ENOMEM);
    438                 return;
    439         }
    440 
    441         fibril_mutex_initialize(&asocket->lock);
    442         asocket->client = client;
     492        rc = tcp_sock_create(client, &asocket);
     493        if (rc != EOK) {
     494                fibril_mutex_unlock(&socket->lock);
     495                async_answer_0(callid, rc);
     496                return;
     497        }
     498
    443499        asocket->conn = conn;
    444500        log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n");
    445501
    446         rc = socket_create(&client->sockets, client->sess, asocket, &asock_id);
     502        rc = tcp_sock_finish_setup(asocket, &asock_id);
    447503        if (rc != EOK) {
     504                tcp_sock_uncreate(asocket);
    448505                fibril_mutex_unlock(&socket->lock);
    449506                async_answer_0(callid, rc);
    450507                return;
    451508        }
     509
     510        fibril_add_ready(asocket->recv_fibril);
     511
    452512        log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n");
    453513
    454         asock_core = socket_cores_find(&client->sockets, asock_id);
    455         assert(asock_core != NULL);
    456 
    457         refresh_answer(&answer, NULL);
    458 
    459         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
     514        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
    460515        SOCKET_SET_SOCKET_ID(answer, asock_id);
    461516        SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in));
    462 
    463         answer_call(callid, asock_core->socket_id, &answer, 3);
    464 
     517       
     518        async_answer_3(callid, asocket->sock_core->socket_id,
     519            IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
     520            IPC_GET_ARG3(answer));
     521       
    465522        /* Push one fragment notification to client's queue */
    466523        log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n");
    467         tcp_sock_notify_data(asock_core);
    468524        fibril_mutex_unlock(&socket->lock);
    469525}
     
    479535        ipc_callid_t wcallid;
    480536        size_t length;
    481         uint8_t buffer[FRAGMENT_SIZE];
     537        uint8_t buffer[TCP_SOCK_FRAGMENT_SIZE];
    482538        tcp_error_t trc;
    483539        int rc;
     
    510566                }
    511567
    512                 if (length > FRAGMENT_SIZE)
    513                         length = FRAGMENT_SIZE;
     568                if (length > TCP_SOCK_FRAGMENT_SIZE)
     569                        length = TCP_SOCK_FRAGMENT_SIZE;
    514570
    515571                rc = async_data_write_finalize(wcallid, buffer, length);
     
    546602        }
    547603
    548         refresh_answer(&answer, NULL);
    549         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    550         answer_call(callid, EOK, &answer, 2);
     604        IPC_SET_ARG1(answer, 0);
     605        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
     606        async_answer_2(callid, EOK, IPC_GET_ARG1(answer),
     607            IPC_GET_ARG2(answer));
    551608        fibril_mutex_unlock(&socket->lock);
    552609}
     
    567624        ipc_call_t answer;
    568625        ipc_callid_t rcallid;
    569         uint8_t buffer[FRAGMENT_SIZE];
    570626        size_t data_len;
    571         xflags_t xflags;
    572         tcp_error_t trc;
    573627        struct sockaddr_in addr;
    574628        tcp_sock_t *rsock;
     
    597651        (void)flags;
    598652
    599         trc = tcp_uc_receive(socket->conn, buffer, FRAGMENT_SIZE, &data_len,
    600             &xflags);
    601         log_msg(LVL_DEBUG, "**** tcp_uc_receive done");
    602 
    603         switch (trc) {
     653        log_msg(LVL_DEBUG, "tcp_sock_recvfrom(): lock recv_buffer_lock");
     654        fibril_mutex_lock(&socket->recv_buffer_lock);
     655        while (socket->recv_buffer_used == 0 && socket->recv_error == TCP_EOK) {
     656                log_msg(LVL_DEBUG, "wait for recv_buffer_cv + recv_buffer_used != 0");
     657                fibril_condvar_wait(&socket->recv_buffer_cv,
     658                    &socket->recv_buffer_lock);
     659        }
     660
     661        log_msg(LVL_DEBUG, "Got data in sock recv_buffer");
     662
     663        data_len = socket->recv_buffer_used;
     664        rc = socket->recv_error;
     665
     666        switch (socket->recv_error) {
    604667        case TCP_EOK:
    605668                rc = EOK;
     
    616679        }
    617680
    618         log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc);
     681        log_msg(LVL_DEBUG, "**** recv result -> %d", rc);
    619682        if (rc != EOK) {
     683                fibril_mutex_unlock(&socket->recv_buffer_lock);
    620684                fibril_mutex_unlock(&socket->lock);
    621685                async_answer_0(callid, rc);
     
    632696                log_msg(LVL_DEBUG, "addr read receive");
    633697                if (!async_data_read_receive(&rcallid, &addr_length)) {
     698                        fibril_mutex_unlock(&socket->recv_buffer_lock);
    634699                        fibril_mutex_unlock(&socket->lock);
    635700                        async_answer_0(callid, EINVAL);
     
    643708                rc = async_data_read_finalize(rcallid, &addr, addr_length);
    644709                if (rc != EOK) {
     710                        fibril_mutex_unlock(&socket->recv_buffer_lock);
    645711                        fibril_mutex_unlock(&socket->lock);
    646712                        async_answer_0(callid, EINVAL);
     
    651717        log_msg(LVL_DEBUG, "data read receive");
    652718        if (!async_data_read_receive(&rcallid, &length)) {
     719                fibril_mutex_unlock(&socket->recv_buffer_lock);
    653720                fibril_mutex_unlock(&socket->lock);
    654721                async_answer_0(callid, EINVAL);
     
    660727
    661728        log_msg(LVL_DEBUG, "data read finalize");
    662         rc = async_data_read_finalize(rcallid, buffer, length);
     729        rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
     730
     731        socket->recv_buffer_used -= length;
     732        log_msg(LVL_DEBUG, "tcp_sock_recvfrom: %zu left in buffer",
     733            socket->recv_buffer_used);
     734        if (socket->recv_buffer_used > 0) {
     735                memmove(socket->recv_buffer, socket->recv_buffer + length,
     736                    socket->recv_buffer_used);
     737                tcp_sock_notify_data(socket->sock_core);
     738        }
     739
     740        fibril_condvar_broadcast(&socket->recv_buffer_cv);
    663741
    664742        if (length < data_len && rc == EOK)
     
    666744
    667745        SOCKET_SET_READ_DATA_LENGTH(answer, length);
    668         answer_call(callid, EOK, &answer, 1);
    669 
    670         /* Push one fragment notification to client's queue */
    671         tcp_sock_notify_data(sock_core);
     746        async_answer_1(callid, EOK, IPC_GET_ARG1(answer));
     747
     748        fibril_mutex_unlock(&socket->recv_buffer_lock);
    672749        fibril_mutex_unlock(&socket->lock);
    673750}
     
    680757        tcp_error_t trc;
    681758        int rc;
    682         uint8_t buffer[FRAGMENT_SIZE];
    683         size_t data_len;
    684         xflags_t xflags;
    685759
    686760        log_msg(LVL_DEBUG, "tcp_sock_close()");
     
    703777                        return;
    704778                }
    705 
    706                 /* Drain incoming data. This should really be done in the background. */
    707                 do {
    708                         trc = tcp_uc_receive(socket->conn, buffer,
    709                             FRAGMENT_SIZE, &data_len, &xflags);
    710                 } while (trc == TCP_EOK);
    711 
    712                 tcp_uc_delete(socket->conn);
    713         }
    714 
    715         rc = socket_destroy(net_sess, socket_id, &client->sockets, &gsock,
     779        }
     780
     781        rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock,
    716782            tcp_free_sock_data);
    717783        if (rc != EOK) {
     
    764830}
    765831
    766 int tcp_sock_connection(async_sess_t *sess, ipc_callid_t iid, ipc_call_t icall)
     832static int tcp_sock_recv_fibril(void *arg)
     833{
     834        tcp_sockdata_t *sock = (tcp_sockdata_t *)arg;
     835        size_t data_len;
     836        xflags_t xflags;
     837        tcp_error_t trc;
     838
     839        log_msg(LVL_DEBUG, "tcp_sock_recv_fibril()");
     840
     841        while (true) {
     842                log_msg(LVL_DEBUG, "call tcp_uc_receive()");
     843                fibril_mutex_lock(&sock->recv_buffer_lock);
     844                while (sock->recv_buffer_used != 0)
     845                        fibril_condvar_wait(&sock->recv_buffer_cv,
     846                            &sock->recv_buffer_lock);
     847
     848                trc = tcp_uc_receive(sock->conn, sock->recv_buffer,
     849                    TCP_SOCK_FRAGMENT_SIZE, &data_len, &xflags);
     850
     851                if (trc != TCP_EOK) {
     852                        sock->recv_error = trc;
     853                        fibril_condvar_broadcast(&sock->recv_buffer_cv);
     854                        fibril_mutex_unlock(&sock->recv_buffer_lock);
     855                        tcp_sock_notify_data(sock->sock_core);
     856                        break;
     857                }
     858
     859                log_msg(LVL_DEBUG, "got data - broadcast recv_buffer_cv");
     860
     861                sock->recv_buffer_used = data_len;
     862                fibril_condvar_broadcast(&sock->recv_buffer_cv);
     863                fibril_mutex_unlock(&sock->recv_buffer_lock);
     864                tcp_sock_notify_data(sock->sock_core);
     865        }
     866
     867        tcp_uc_delete(sock->conn);
     868
     869        return 0;
     870}
     871
     872static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    767873{
    768874        ipc_callid_t callid;
     
    773879        async_answer_0(iid, EOK);
    774880
    775         client.sess = sess;
     881        client.sess = async_callback_receive(EXCHANGE_SERIALIZE);
    776882        socket_cores_initialize(&client.sockets);
    777883
     
    825931        }
    826932
    827         return EOK;
     933        /* Clean up */
     934        log_msg(LVL_DEBUG, "tcp_sock_connection: Clean up");
     935        async_hangup(client.sess);
     936        socket_cores_release(NULL, &client.sockets, &gsock, tcp_free_sock_data);
    828937}
    829938
Note: See TracChangeset for help on using the changeset viewer.