Ignore:
File:
1 edited

Legend:

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

    r7c912b6 r0d520a2  
    4242#include <ipc/services.h>
    4343#include <ipc/socket.h>
     44#include <net/modules.h>
    4445#include <net/socket.h>
    4546#include <ns.h>
     
    5152#include "ucall.h"
    5253
     54#define FRAGMENT_SIZE 1024
     55
    5356#define MAX_BACKLOG 128
    5457
     
    6467static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    6568static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg);
    66 static int tcp_sock_recv_fibril(void *arg);
    6769
    6870int tcp_sock_init(void)
     
    9698        async_exch_t *exch = async_exchange_begin(sock_core->sess);
    9799        async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
    98             TCP_SOCK_FRAGMENT_SIZE, 0, 0, 1);
     100            FRAGMENT_SIZE, 0, 0, 1);
    99101        async_exchange_end(exch);
    100102}
     
    105107        async_exch_t *exch = async_exchange_begin(lsock_core->sess);
    106108        async_msg_5(exch, NET_SOCKET_ACCEPTED, (sysarg_t)lsock_core->socket_id,
    107             TCP_SOCK_FRAGMENT_SIZE, 0, 0, 0);
     109            FRAGMENT_SIZE, 0, 0, 0);
    108110        async_exchange_end(exch);
    109111}
    110112
    111 static int tcp_sock_create(tcp_client_t *client, tcp_sockdata_t **rsock)
     113static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    112114{
    113115        tcp_sockdata_t *sock;
    114 
    115         log_msg(LVL_DEBUG, "tcp_sock_create()");
    116         *rsock = NULL;
    117 
    118         sock = calloc(sizeof(tcp_sockdata_t), 1);
    119         if (sock == NULL)
    120                 return ENOMEM;
    121 
    122         fibril_mutex_initialize(&sock->lock);
    123         sock->client = client;
    124 
    125         sock->recv_buffer_used = 0;
    126         sock->recv_error = TCP_EOK;
    127         fibril_mutex_initialize(&sock->recv_buffer_lock);
    128         fibril_condvar_initialize(&sock->recv_buffer_cv);
    129         list_initialize(&sock->ready);
    130 
    131         *rsock = sock;
    132         return EOK;
    133 }
    134 
    135 static void tcp_sock_uncreate(tcp_sockdata_t *sock)
    136 {
    137         log_msg(LVL_DEBUG, "tcp_sock_uncreate()");
    138         free(sock);
    139 }
    140 
    141 static int tcp_sock_finish_setup(tcp_sockdata_t *sock, int *sock_id)
    142 {
    143116        socket_core_t *sock_core;
    144         int rc;
    145 
    146         log_msg(LVL_DEBUG, "tcp_sock_finish_setup()");
    147 
    148         sock->recv_fibril = fibril_create(tcp_sock_recv_fibril, sock);
    149         if (sock->recv_fibril == 0)
    150                 return ENOMEM;
    151 
    152         rc = socket_create(&sock->client->sockets, sock->client->sess,
    153             sock, sock_id);
    154 
    155         if (rc != EOK)
    156                 return rc;
    157 
    158         sock_core = socket_cores_find(&sock->client->sockets, *sock_id);
    159         assert(sock_core != NULL);
    160         sock->sock_core = sock_core;
    161 
    162         return EOK;
    163 }
    164 
    165 static void tcp_sock_socket(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    166 {
    167         tcp_sockdata_t *sock;
    168117        int sock_id;
    169118        int rc;
     
    171120
    172121        log_msg(LVL_DEBUG, "tcp_sock_socket()");
    173 
    174         rc = tcp_sock_create(client, &sock);
    175         if (rc != EOK) {
    176                 async_answer_0(callid, rc);
    177                 return;
    178         }
    179 
     122        sock = calloc(sizeof(tcp_sockdata_t), 1);
     123        if (sock == NULL) {
     124                async_answer_0(callid, ENOMEM);
     125                return;
     126        }
     127
     128        fibril_mutex_initialize(&sock->lock);
     129        sock->client = client;
    180130        sock->laddr.ipv4 = TCP_IPV4_ANY;
    181131        sock->lconn = NULL;
    182132        sock->backlog = 0;
     133        list_initialize(&sock->ready);
    183134
    184135        sock_id = SOCKET_GET_SOCKET_ID(call);
    185         rc = tcp_sock_finish_setup(sock, &sock_id);
     136        rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
    186137        if (rc != EOK) {
    187                 tcp_sock_uncreate(sock);
    188138                async_answer_0(callid, rc);
    189139                return;
    190140        }
    191141
     142        sock_core = socket_cores_find(&client->sockets, sock_id);
     143        assert(sock_core != NULL);
     144        sock->sock_core = sock_core;
     145
     146        refresh_answer(&answer, NULL);
    192147        SOCKET_SET_SOCKET_ID(answer, sock_id);
    193148
    194         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
     149        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    195150        SOCKET_SET_HEADER_SIZE(answer, sizeof(tcp_header_t));
    196        
    197         async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
    198             IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
     151        answer_call(callid, EOK, &answer, 3);
    199152}
    200153
     
    408361        }
    409362
    410         if (rc == EOK)
    411                 fibril_add_ready(socket->recv_fibril);
    412 
    413363        async_answer_0(callid, rc);
     364
     365        /* Push one fragment notification to client's queue */
     366        tcp_sock_notify_data(sock_core);
     367        log_msg(LVL_DEBUG, "tcp_sock_connect(): notify conn\n");
    414368}
    415369
     
    420374        int asock_id;
    421375        socket_core_t *sock_core;
     376        socket_core_t *asock_core;
    422377        tcp_sockdata_t *socket;
    423378        tcp_sockdata_t *asocket;
     
    489444        /* Allocate socket for accepted connection */
    490445
    491         rc = tcp_sock_create(client, &asocket);
    492         if (rc != EOK) {
    493                 fibril_mutex_unlock(&socket->lock);
    494                 async_answer_0(callid, rc);
    495                 return;
    496         }
    497 
     446        log_msg(LVL_DEBUG, "tcp_sock_accept(): allocate asocket\n");
     447        asocket = calloc(sizeof(tcp_sockdata_t), 1);
     448        if (asocket == NULL) {
     449                fibril_mutex_unlock(&socket->lock);
     450                async_answer_0(callid, ENOMEM);
     451                return;
     452        }
     453
     454        fibril_mutex_initialize(&asocket->lock);
     455        asocket->client = client;
    498456        asocket->conn = conn;
    499457        log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n");
    500458
    501         rc = tcp_sock_finish_setup(asocket, &asock_id);
     459        rc = socket_create(&client->sockets, client->sess, asocket, &asock_id);
    502460        if (rc != EOK) {
    503                 tcp_sock_uncreate(asocket);
    504461                fibril_mutex_unlock(&socket->lock);
    505462                async_answer_0(callid, rc);
    506463                return;
    507464        }
    508 
    509         fibril_add_ready(asocket->recv_fibril);
    510 
    511465        log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n");
    512466
    513         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
     467        asock_core = socket_cores_find(&client->sockets, asock_id);
     468        assert(asock_core != NULL);
     469
     470        refresh_answer(&answer, NULL);
     471
     472        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    514473        SOCKET_SET_SOCKET_ID(answer, asock_id);
    515474        SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(struct sockaddr_in));
    516        
    517         async_answer_3(callid, asocket->sock_core->socket_id,
    518             IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    519             IPC_GET_ARG3(answer));
    520        
     475
     476        answer_call(callid, asock_core->socket_id, &answer, 3);
     477
    521478        /* Push one fragment notification to client's queue */
    522479        log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n");
     480        tcp_sock_notify_data(asock_core);
    523481        fibril_mutex_unlock(&socket->lock);
    524482}
     
    534492        ipc_callid_t wcallid;
    535493        size_t length;
    536         uint8_t buffer[TCP_SOCK_FRAGMENT_SIZE];
     494        uint8_t buffer[FRAGMENT_SIZE];
    537495        tcp_error_t trc;
    538496        int rc;
     
    565523                }
    566524
    567                 if (length > TCP_SOCK_FRAGMENT_SIZE)
    568                         length = TCP_SOCK_FRAGMENT_SIZE;
     525                if (length > FRAGMENT_SIZE)
     526                        length = FRAGMENT_SIZE;
    569527
    570528                rc = async_data_write_finalize(wcallid, buffer, length);
     
    601559        }
    602560
    603         IPC_SET_ARG1(answer, 0);
    604         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
    605         async_answer_2(callid, EOK, IPC_GET_ARG1(answer),
    606             IPC_GET_ARG2(answer));
     561        refresh_answer(&answer, NULL);
     562        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
     563        answer_call(callid, EOK, &answer, 2);
    607564        fibril_mutex_unlock(&socket->lock);
    608565}
     
    623580        ipc_call_t answer;
    624581        ipc_callid_t rcallid;
     582        uint8_t buffer[FRAGMENT_SIZE];
    625583        size_t data_len;
     584        xflags_t xflags;
     585        tcp_error_t trc;
    626586        struct sockaddr_in addr;
    627587        tcp_sock_t *rsock;
     
    650610        (void)flags;
    651611
    652         log_msg(LVL_DEBUG, "tcp_sock_recvfrom(): lock recv_buffer_lock");
    653         fibril_mutex_lock(&socket->recv_buffer_lock);
    654         while (socket->recv_buffer_used == 0 && socket->recv_error == TCP_EOK) {
    655                 log_msg(LVL_DEBUG, "wait for recv_buffer_cv + recv_buffer_used != 0");
    656                 fibril_condvar_wait(&socket->recv_buffer_cv,
    657                     &socket->recv_buffer_lock);
    658         }
    659 
    660         log_msg(LVL_DEBUG, "Got data in sock recv_buffer");
    661 
    662         data_len = socket->recv_buffer_used;
    663         rc = socket->recv_error;
    664 
    665         switch (socket->recv_error) {
     612        trc = tcp_uc_receive(socket->conn, buffer, FRAGMENT_SIZE, &data_len,
     613            &xflags);
     614        log_msg(LVL_DEBUG, "**** tcp_uc_receive done");
     615
     616        switch (trc) {
    666617        case TCP_EOK:
    667618                rc = EOK;
     
    678629        }
    679630
    680         log_msg(LVL_DEBUG, "**** recv result -> %d", rc);
     631        log_msg(LVL_DEBUG, "**** tcp_uc_receive -> %d", rc);
    681632        if (rc != EOK) {
    682                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    683633                fibril_mutex_unlock(&socket->lock);
    684634                async_answer_0(callid, rc);
     
    695645                log_msg(LVL_DEBUG, "addr read receive");
    696646                if (!async_data_read_receive(&rcallid, &addr_length)) {
    697                         fibril_mutex_unlock(&socket->recv_buffer_lock);
    698647                        fibril_mutex_unlock(&socket->lock);
    699648                        async_answer_0(callid, EINVAL);
     
    707656                rc = async_data_read_finalize(rcallid, &addr, addr_length);
    708657                if (rc != EOK) {
    709                         fibril_mutex_unlock(&socket->recv_buffer_lock);
    710658                        fibril_mutex_unlock(&socket->lock);
    711659                        async_answer_0(callid, EINVAL);
     
    716664        log_msg(LVL_DEBUG, "data read receive");
    717665        if (!async_data_read_receive(&rcallid, &length)) {
    718                 fibril_mutex_unlock(&socket->recv_buffer_lock);
    719666                fibril_mutex_unlock(&socket->lock);
    720667                async_answer_0(callid, EINVAL);
     
    726673
    727674        log_msg(LVL_DEBUG, "data read finalize");
    728         rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
    729 
    730         socket->recv_buffer_used -= length;
    731         log_msg(LVL_DEBUG, "tcp_sock_recvfrom: %zu left in buffer",
    732             socket->recv_buffer_used);
    733         if (socket->recv_buffer_used > 0) {
    734                 memmove(socket->recv_buffer, socket->recv_buffer + length,
    735                     socket->recv_buffer_used);
    736                 tcp_sock_notify_data(socket->sock_core);
    737         }
    738 
    739         fibril_condvar_broadcast(&socket->recv_buffer_cv);
     675        rc = async_data_read_finalize(rcallid, buffer, length);
    740676
    741677        if (length < data_len && rc == EOK)
     
    743679
    744680        SOCKET_SET_READ_DATA_LENGTH(answer, length);
    745         async_answer_1(callid, EOK, IPC_GET_ARG1(answer));
    746 
    747         fibril_mutex_unlock(&socket->recv_buffer_lock);
     681        answer_call(callid, EOK, &answer, 1);
     682
     683        /* Push one fragment notification to client's queue */
     684        tcp_sock_notify_data(sock_core);
    748685        fibril_mutex_unlock(&socket->lock);
    749686}
     
    756693        tcp_error_t trc;
    757694        int rc;
     695        uint8_t buffer[FRAGMENT_SIZE];
     696        size_t data_len;
     697        xflags_t xflags;
    758698
    759699        log_msg(LVL_DEBUG, "tcp_sock_close()");
     
    776716                        return;
    777717                }
     718
     719                /* Drain incoming data. This should really be done in the background. */
     720                do {
     721                        trc = tcp_uc_receive(socket->conn, buffer,
     722                            FRAGMENT_SIZE, &data_len, &xflags);
     723                } while (trc == TCP_EOK);
     724
     725                tcp_uc_delete(socket->conn);
    778726        }
    779727
     
    827775        tcp_sock_notify_aconn(socket->sock_core);
    828776        fibril_mutex_unlock(&socket->lock);
    829 }
    830 
    831 static int tcp_sock_recv_fibril(void *arg)
    832 {
    833         tcp_sockdata_t *sock = (tcp_sockdata_t *)arg;
    834         size_t data_len;
    835         xflags_t xflags;
    836         tcp_error_t trc;
    837 
    838         log_msg(LVL_DEBUG, "tcp_sock_recv_fibril()");
    839 
    840         while (true) {
    841                 log_msg(LVL_DEBUG, "call tcp_uc_receive()");
    842                 fibril_mutex_lock(&sock->recv_buffer_lock);
    843                 while (sock->recv_buffer_used != 0)
    844                         fibril_condvar_wait(&sock->recv_buffer_cv,
    845                             &sock->recv_buffer_lock);
    846 
    847                 trc = tcp_uc_receive(sock->conn, sock->recv_buffer,
    848                     TCP_SOCK_FRAGMENT_SIZE, &data_len, &xflags);
    849 
    850                 if (trc != TCP_EOK) {
    851                         sock->recv_error = trc;
    852                         fibril_condvar_broadcast(&sock->recv_buffer_cv);
    853                         fibril_mutex_unlock(&sock->recv_buffer_lock);
    854                         tcp_sock_notify_data(sock->sock_core);
    855                         break;
    856                 }
    857 
    858                 log_msg(LVL_DEBUG, "got data - broadcast recv_buffer_cv");
    859 
    860                 sock->recv_buffer_used = data_len;
    861                 fibril_condvar_broadcast(&sock->recv_buffer_cv);
    862                 fibril_mutex_unlock(&sock->recv_buffer_lock);
    863                 tcp_sock_notify_data(sock->sock_core);
    864         }
    865 
    866         tcp_uc_delete(sock->conn);
    867 
    868         return 0;
    869777}
    870778
Note: See TracChangeset for help on using the changeset viewer.