Ignore:
File:
1 edited

Legend:

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

    r69a93df7 r02a09ed  
    4343#include <ipc/services.h>
    4444#include <ipc/socket.h>
    45 #include <net/modules.h>
    4645#include <net/socket.h>
    4746#include <ns.h>
     
    5251#include "ucall.h"
    5352
    54 #define FRAGMENT_SIZE 1024
    55 
    5653/** Free ports pool start. */
    5754#define UDP_FREE_PORTS_START            1025
     
    6461
    6562static void udp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
     63static int udp_sock_recv_fibril(void *arg);
    6664
    6765int udp_sock_init(void)
    6866{
    69         int rc;
    70 
    7167        socket_ports_initialize(&gsock);
    72 
     68       
    7369        async_set_client_connection(udp_sock_connection);
    74 
    75         rc = service_register(SERVICE_UDP);
     70       
     71        int rc = service_register(SERVICE_UDP);
    7672        if (rc != EOK)
    7773                return EEXIST;
    78 
     74       
    7975        return EOK;
    8076}
     
    8682        socket = (udp_sockdata_t *)sock_core->specific_data;
    8783        (void)socket;
     84
     85        /* XXX We need to force the receive fibril to quit */
    8886}
    8987
    9088static void udp_sock_notify_data(socket_core_t *sock_core)
    9189{
    92         log_msg(LVL_DEBUG, "udp_sock_notify_data(%d)", sock_core->socket_id);
     90        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_notify_data(%d)", sock_core->socket_id);
    9391        async_exch_t *exch = async_exchange_begin(sock_core->sess);
    94         async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
    95             FRAGMENT_SIZE, 0, 0, 1);
     92        async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t) sock_core->socket_id,
     93            UDP_FRAGMENT_SIZE, 0, 0, 1);
    9694        async_exchange_end(exch);
    9795}
     
    105103        ipc_call_t answer;
    106104
    107         log_msg(LVL_DEBUG, "udp_sock_socket()");
    108         sock = calloc(sizeof(udp_sockdata_t), 1);
     105        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_socket()");
     106        sock = calloc(1, sizeof(udp_sockdata_t));
    109107        if (sock == NULL) {
    110108                async_answer_0(callid, ENOMEM);
     
    115113        sock->client = client;
    116114
     115        sock->recv_buffer_used = 0;
     116        sock->recv_error = UDP_EOK;
     117        fibril_mutex_initialize(&sock->recv_buffer_lock);
     118        fibril_condvar_initialize(&sock->recv_buffer_cv);
     119
    117120        rc = udp_uc_create(&sock->assoc);
    118121        if (rc != EOK) {
     122                free(sock);
     123                async_answer_0(callid, rc);
     124                return;
     125        }
     126
     127        sock->recv_fibril = fibril_create(udp_sock_recv_fibril, sock);
     128        if (sock->recv_fibril == 0) {
     129                udp_uc_destroy(sock->assoc);
     130                free(sock);
     131                async_answer_0(callid, ENOMEM);
     132                return;
     133        }
     134
     135        sock_id = SOCKET_GET_SOCKET_ID(call);
     136        rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
     137        if (rc != EOK) {
     138                fibril_destroy(sock->recv_fibril);
    119139                udp_uc_destroy(sock->assoc);
    120140                free(sock);
     
    123143        }
    124144
    125         sock_id = SOCKET_GET_SOCKET_ID(call);
    126         rc = socket_create(&client->sockets, client->sess, sock, &sock_id);
    127         if (rc != EOK) {
    128                 async_answer_0(callid, rc);
    129                 return;
    130         }
     145        fibril_add_ready(sock->recv_fibril);
    131146
    132147        sock_core = socket_cores_find(&client->sockets, sock_id);
    133148        assert(sock_core != NULL);
    134149        sock->sock_core = sock_core;
    135 
    136 
    137         refresh_answer(&answer, NULL);
     150       
    138151        SOCKET_SET_SOCKET_ID(answer, sock_id);
    139152
    140         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
     153        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE);
    141154        SOCKET_SET_HEADER_SIZE(answer, sizeof(udp_header_t));
    142         answer_call(callid, EOK, &answer, 3);
     155        async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
     156            IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
    143157}
    144158
    145159static void udp_sock_bind(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    146160{
    147         int rc;
    148         struct sockaddr_in *addr;
    149         size_t addr_size;
    150         socket_core_t *sock_core;
    151         udp_sockdata_t *socket;
    152         udp_sock_t fsock;
    153         udp_error_t urc;
    154 
    155         log_msg(LVL_DEBUG, "udp_sock_bind()");
    156         log_msg(LVL_DEBUG, " - async_data_write_accept");
    157 
    158         addr = NULL;
    159 
    160         rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_size);
     161        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_bind()");
     162        log_msg(LOG_DEFAULT, LVL_DEBUG, " - async_data_write_accept");
     163       
     164        struct sockaddr_in6 *addr6 = NULL;
     165        size_t addr_len;
     166        int rc = async_data_write_accept((void **) &addr6, false, 0, 0, 0, &addr_len);
    161167        if (rc != EOK) {
    162168                async_answer_0(callid, rc);
     169                return;
     170        }
     171       
     172        if ((addr_len != sizeof(struct sockaddr_in)) &&
     173            (addr_len != sizeof(struct sockaddr_in6))) {
     174                async_answer_0(callid, EINVAL);
    163175                goto out;
    164176        }
    165 
    166         log_msg(LVL_DEBUG, " - call socket_bind");
     177       
     178        struct sockaddr_in *addr = (struct sockaddr_in *) addr6;
     179       
     180        log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_bind");
     181       
    167182        rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
    168             addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
     183            addr6, addr_len, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
    169184            last_used_port);
    170185        if (rc != EOK) {
     
    172187                goto out;
    173188        }
    174 
    175         if (addr_size != sizeof(struct sockaddr_in)) {
    176                 async_answer_0(callid, EINVAL);
    177                 goto out;
    178         }
    179 
    180         log_msg(LVL_DEBUG, " - call socket_cores_find");
    181         sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call));
     189       
     190        log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_cores_find");
     191       
     192        socket_core_t *sock_core = socket_cores_find(&client->sockets,
     193            SOCKET_GET_SOCKET_ID(call));
    182194        if (sock_core == NULL) {
    183195                async_answer_0(callid, ENOENT);
    184196                goto out;
    185197        }
    186 
    187         socket = (udp_sockdata_t *)sock_core->specific_data;
    188 
    189         fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
    190         fsock.port = sock_core->port;
    191         urc = udp_uc_set_local(socket->assoc, &fsock);
    192 
     198       
     199        udp_sockdata_t *socket =
     200            (udp_sockdata_t *) sock_core->specific_data;
     201       
     202        udp_sock_t fsocket;
     203       
     204        fsocket.port = sock_core->port;
     205       
     206        switch (addr->sin_family) {
     207        case AF_INET:
     208                inet_sockaddr_in_addr(addr, &fsocket.addr);
     209                break;
     210        case AF_INET6:
     211                inet_sockaddr_in6_addr(addr6, &fsocket.addr);
     212                break;
     213        default:
     214                async_answer_0(callid, EINVAL);
     215                goto out;
     216        }
     217       
     218        udp_error_t urc = udp_uc_set_local(socket->assoc, &fsocket);
     219       
    193220        switch (urc) {
    194221        case UDP_EOK:
     
    207234                assert(false);
    208235        }
    209 
    210         udp_sock_notify_data(sock_core);
    211 
    212         log_msg(LVL_DEBUG, " - success");
     236       
     237        log_msg(LOG_DEFAULT, LVL_DEBUG, " - success");
    213238        async_answer_0(callid, rc);
     239       
    214240out:
    215         if (addr != NULL)
    216                 free(addr);
     241        if (addr6 != NULL)
     242                free(addr6);
    217243}
    218244
    219245static void udp_sock_listen(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    220246{
    221         log_msg(LVL_DEBUG, "udp_sock_listen()");
     247        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_listen()");
    222248        async_answer_0(callid, ENOTSUP);
    223249}
     
    225251static void udp_sock_connect(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    226252{
    227         log_msg(LVL_DEBUG, "udp_sock_connect()");
     253        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connect()");
    228254        async_answer_0(callid, ENOTSUP);
    229255}
     
    231257static void udp_sock_accept(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    232258{
    233         log_msg(LVL_DEBUG, "udp_sock_accept()");
     259        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_accept()");
    234260        async_answer_0(callid, ENOTSUP);
    235261}
     
    237263static void udp_sock_sendto(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    238264{
    239         int socket_id;
    240         int fragments;
    241         int index;
     265        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_send()");
     266       
     267        struct sockaddr_in6 *addr6 = NULL;
    242268        struct sockaddr_in *addr;
    243         size_t addr_size;
    244         socket_core_t *sock_core;
    245         udp_sockdata_t *socket;
    246         udp_sock_t fsock, *fsockp;
    247         ipc_call_t answer;
    248         ipc_callid_t wcallid;
    249         size_t length;
    250         uint8_t buffer[FRAGMENT_SIZE];
    251         udp_error_t urc;
    252         int rc;
    253 
    254         log_msg(LVL_DEBUG, "udp_sock_send()");
    255 
    256         addr = NULL;
    257 
     269        udp_sock_t fsocket;
     270        udp_sock_t *fsocket_ptr;
     271       
    258272        if (IPC_GET_IMETHOD(call) == NET_SOCKET_SENDTO) {
    259                 rc = async_data_write_accept((void **) &addr, false,
    260                     0, 0, 0, &addr_size);
     273                size_t addr_len;
     274                int rc = async_data_write_accept((void **) &addr6, false,
     275                    0, 0, 0, &addr_len);
     276                if (rc != EOK) {
     277                        async_answer_0(callid, rc);
     278                        return;
     279                }
     280               
     281                if ((addr_len != sizeof(struct sockaddr_in)) &&
     282                    (addr_len != sizeof(struct sockaddr_in6))) {
     283                        async_answer_0(callid, EINVAL);
     284                        goto out;
     285                }
     286               
     287                addr = (struct sockaddr_in *) addr6;
     288               
     289                switch (addr->sin_family) {
     290                case AF_INET:
     291                        inet_sockaddr_in_addr(addr, &fsocket.addr);
     292                        break;
     293                case AF_INET6:
     294                        inet_sockaddr_in6_addr(addr6, &fsocket.addr);
     295                        break;
     296                default:
     297                        async_answer_0(callid, EINVAL);
     298                        goto out;
     299                }
     300               
     301                fsocket.port = uint16_t_be2host(addr->sin_port);
     302                fsocket_ptr = &fsocket;
     303        } else
     304                fsocket_ptr = NULL;
     305       
     306        int socket_id = SOCKET_GET_SOCKET_ID(call);
     307       
     308        SOCKET_GET_FLAGS(call);
     309       
     310        socket_core_t *sock_core =
     311            socket_cores_find(&client->sockets, socket_id);
     312        if (sock_core == NULL) {
     313                async_answer_0(callid, ENOTSOCK);
     314                goto out;
     315        }
     316       
     317        udp_sockdata_t *socket =
     318            (udp_sockdata_t *) sock_core->specific_data;
     319       
     320        if (sock_core->port <= 0) {
     321                /* Implicitly bind socket to port */
     322                int rc = socket_bind_free_port(&gsock, sock_core,
     323                    UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, last_used_port);
    261324                if (rc != EOK) {
    262325                        async_answer_0(callid, rc);
    263326                        goto out;
    264327                }
    265 
    266                 if (addr_size != sizeof(struct sockaddr_in)) {
    267                         async_answer_0(callid, EINVAL);
     328               
     329                assert(sock_core->port > 0);
     330               
     331                udp_error_t urc = udp_uc_set_local_port(socket->assoc,
     332                    sock_core->port);
     333               
     334                if (urc != UDP_EOK) {
     335                        // TODO: better error handling
     336                        async_answer_0(callid, EINTR);
    268337                        goto out;
    269338                }
    270 
    271                 fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
    272                 fsock.port = uint16_t_be2host(addr->sin_port);
    273                 fsockp = &fsock;
    274         } else {
    275                 fsockp = NULL;
    276         }
    277 
    278         socket_id = SOCKET_GET_SOCKET_ID(call);
    279         fragments = SOCKET_GET_DATA_FRAGMENTS(call);
    280         SOCKET_GET_FLAGS(call);
    281 
    282         sock_core = socket_cores_find(&client->sockets, socket_id);
    283         if (sock_core == NULL) {
    284                 async_answer_0(callid, ENOTSOCK);
    285                 goto out;
    286         }
    287 
    288         if (sock_core->port == 0) {
    289                 /* Implicitly bind socket to port */
    290                 rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
    291                     addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
    292                     last_used_port);
    293                 if (rc != EOK) {
    294                         async_answer_0(callid, rc);
    295                         goto out;
    296                 }
    297 
    298                 udp_sock_notify_data(sock_core);
    299         }
    300 
    301         socket = (udp_sockdata_t *)sock_core->specific_data;
     339               
     340                last_used_port = sock_core->port;
     341        }
     342       
    302343        fibril_mutex_lock(&socket->lock);
    303 
    304         if (socket->assoc->ident.local.addr.ipv4 == UDP_IPV4_ANY) {
     344       
     345        if (inet_addr_is_any(&socket->assoc->ident.local.addr)) {
    305346                /* Determine local IP address */
    306                 inet_addr_t loc_addr, rem_addr;
    307 
    308                 rem_addr.ipv4 = fsockp ? fsock.addr.ipv4 :
    309                     socket->assoc->ident.foreign.addr.ipv4;
    310 
    311                 rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
     347                inet_addr_t loc_addr;
     348                inet_addr_t rem_addr;
     349               
     350                rem_addr = fsocket_ptr ? fsocket.addr :
     351                    socket->assoc->ident.foreign.addr;
     352               
     353                int rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
    312354                if (rc != EOK) {
    313355                        fibril_mutex_unlock(&socket->lock);
    314356                        async_answer_0(callid, rc);
    315                         log_msg(LVL_DEBUG, "udp_sock_sendto: Failed to "
     357                        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_sendto: Failed to "
    316358                            "determine local address.");
    317359                        return;
    318360                }
    319 
    320                 socket->assoc->ident.local.addr.ipv4 = loc_addr.ipv4;
    321                 log_msg(LVL_DEBUG, "Local IP address is %x",
    322                     socket->assoc->ident.local.addr.ipv4);
    323         }
    324 
    325 
     361               
     362                socket->assoc->ident.local.addr = loc_addr;
     363        }
     364       
    326365        assert(socket->assoc != NULL);
    327 
    328         for (index = 0; index < fragments; index++) {
     366       
     367        int fragments = SOCKET_GET_DATA_FRAGMENTS(call);
     368        for (int index = 0; index < fragments; index++) {
     369                ipc_callid_t wcallid;
     370                size_t length;
     371               
    329372                if (!async_data_write_receive(&wcallid, &length)) {
    330373                        fibril_mutex_unlock(&socket->lock);
     
    332375                        goto out;
    333376                }
    334 
    335                 if (length > FRAGMENT_SIZE)
    336                         length = FRAGMENT_SIZE;
    337 
    338                 rc = async_data_write_finalize(wcallid, buffer, length);
     377               
     378                if (length > UDP_FRAGMENT_SIZE)
     379                        length = UDP_FRAGMENT_SIZE;
     380               
     381                uint8_t buffer[UDP_FRAGMENT_SIZE];
     382                int rc = async_data_write_finalize(wcallid, buffer, length);
    339383                if (rc != EOK) {
    340384                        fibril_mutex_unlock(&socket->lock);
     
    342386                        goto out;
    343387                }
    344 
    345                 urc = udp_uc_send(socket->assoc, fsockp, buffer, length, 0);
    346 
     388               
     389                udp_error_t urc =
     390                    udp_uc_send(socket->assoc, fsocket_ptr, buffer, length, 0);
     391               
    347392                switch (urc) {
    348393                case UDP_EOK:
    349394                        rc = EOK;
    350395                        break;
    351 /*              case TCP_ENOTEXIST:
    352                         rc = ENOTCONN;
    353                         break;
    354                 case TCP_ECLOSING:
    355                         rc = ENOTCONN;
    356                         break;
    357                 case TCP_ERESET:
    358                         rc = ECONNABORTED;
    359                         break;*/
     396                case UDP_ENORES:
     397                        rc = ENOMEM;
     398                        break;
     399                case UDP_EUNSPEC:
     400                        rc = EINVAL;
     401                        break;
     402                case UDP_ENOROUTE:
     403                        rc = EIO;
     404                        break;
    360405                default:
    361406                        assert(false);
    362407                }
    363 
     408               
    364409                if (rc != EOK) {
    365410                        fibril_mutex_unlock(&socket->lock);
     
    368413                }
    369414        }
    370 
    371         refresh_answer(&answer, NULL);
    372         SOCKET_SET_DATA_FRAGMENT_SIZE(answer, FRAGMENT_SIZE);
    373         answer_call(callid, EOK, &answer, 2);
     415       
     416        ipc_call_t answer;
     417       
     418        IPC_SET_ARG1(answer, 0);
     419        SOCKET_SET_DATA_FRAGMENT_SIZE(answer, UDP_FRAGMENT_SIZE);
     420        async_answer_2(callid, EOK, IPC_GET_ARG1(answer),
     421            IPC_GET_ARG2(answer));
    374422        fibril_mutex_unlock(&socket->lock);
     423       
    375424out:
    376         if (addr != NULL)
    377                 free(addr);
     425        if (addr6 != NULL)
     426                free(addr6);
    378427}
    379428
    380429static void udp_sock_recvfrom(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    381430{
    382         int socket_id;
    383         int flags;
    384         size_t addr_length, length;
    385         socket_core_t *sock_core;
    386         udp_sockdata_t *socket;
    387         ipc_call_t answer;
    388         ipc_callid_t rcallid;
    389         uint8_t buffer[FRAGMENT_SIZE];
    390         size_t data_len;
    391         xflags_t xflags;
    392         udp_error_t urc;
    393         struct sockaddr_in addr;
    394         udp_sock_t rsock;
    395         int rc;
    396 
    397         log_msg(LVL_DEBUG, "%p: udp_sock_recv[from]()", client);
    398 
    399         socket_id = SOCKET_GET_SOCKET_ID(call);
    400         flags = SOCKET_GET_FLAGS(call);
    401 
    402         sock_core = socket_cores_find(&client->sockets, socket_id);
     431        log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: udp_sock_recv[from]()", client);
     432       
     433        int socket_id = SOCKET_GET_SOCKET_ID(call);
     434       
     435        socket_core_t *sock_core =
     436            socket_cores_find(&client->sockets, socket_id);
    403437        if (sock_core == NULL) {
    404438                async_answer_0(callid, ENOTSOCK);
    405439                return;
    406440        }
    407 
    408         socket = (udp_sockdata_t *)sock_core->specific_data;
     441       
     442        udp_sockdata_t *socket =
     443            (udp_sockdata_t *) sock_core->specific_data;
     444       
    409445        fibril_mutex_lock(&socket->lock);
    410 
     446       
    411447        if (socket->assoc == NULL) {
    412448                fibril_mutex_unlock(&socket->lock);
     
    414450                return;
    415451        }
    416 
    417         (void)flags;
    418 
    419         urc = udp_uc_receive(socket->assoc, buffer, FRAGMENT_SIZE, &data_len,
    420             &xflags, &rsock);
    421         log_msg(LVL_DEBUG, "**** udp_uc_receive done, data_len=%zu", data_len);
    422 
     452       
     453        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): lock recv_buffer lock");
     454       
     455        fibril_mutex_lock(&socket->recv_buffer_lock);
     456       
     457        while ((socket->recv_buffer_used == 0) &&
     458            (socket->recv_error == UDP_EOK)) {
     459                log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): wait for cv");
     460                fibril_condvar_wait(&socket->recv_buffer_cv,
     461                    &socket->recv_buffer_lock);
     462        }
     463       
     464        log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer");
     465       
     466        size_t data_len = socket->recv_buffer_used;
     467        udp_error_t urc = socket->recv_error;
     468       
     469        log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv data_len=%zu", data_len);
     470       
     471        int rc;
     472       
    423473        switch (urc) {
    424474        case UDP_EOK:
     
    435485                assert(false);
    436486        }
    437 
    438         log_msg(LVL_DEBUG, "**** udp_uc_receive -> %d", rc);
     487       
     488        log_msg(LOG_DEFAULT, LVL_DEBUG, "**** udp_uc_receive -> %d", rc);
     489       
    439490        if (rc != EOK) {
     491                fibril_mutex_unlock(&socket->recv_buffer_lock);
    440492                fibril_mutex_unlock(&socket->lock);
    441493                async_answer_0(callid, rc);
    442494                return;
    443495        }
    444 
     496       
     497        ipc_callid_t rcallid;
     498        size_t addr_size = 0;
     499       
    445500        if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) {
    446                 /* Fill addr */
    447                 addr.sin_family = AF_INET;
    448                 addr.sin_addr.s_addr = host2uint32_t_be(rsock.addr.ipv4);
    449                 addr.sin_port = host2uint16_t_be(rsock.port);
    450 
    451                 log_msg(LVL_DEBUG, "addr read receive");
    452                 if (!async_data_read_receive(&rcallid, &addr_length)) {
     501                /* Fill address */
     502                udp_sock_t *rsock = &socket->recv_fsock;
     503                struct sockaddr_in addr;
     504                struct sockaddr_in6 addr6;
     505                size_t addr_length;
     506               
     507                uint16_t addr_af = inet_addr_sockaddr_in(&rsock->addr, &addr,
     508                    &addr6);
     509               
     510                switch (addr_af) {
     511                case AF_INET:
     512                        addr.sin_port = host2uint16_t_be(rsock->port);
     513                       
     514                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
     515                        if (!async_data_read_receive(&rcallid, &addr_length)) {
     516                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     517                                fibril_mutex_unlock(&socket->lock);
     518                                async_answer_0(callid, EINVAL);
     519                                return;
     520                        }
     521                       
     522                        if (addr_length > sizeof(addr))
     523                                addr_length = sizeof(addr);
     524                       
     525                        addr_size = sizeof(addr);
     526                       
     527                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
     528                        rc = async_data_read_finalize(rcallid, &addr, addr_length);
     529                        if (rc != EOK) {
     530                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     531                                fibril_mutex_unlock(&socket->lock);
     532                                async_answer_0(callid, EINVAL);
     533                                return;
     534                        }
     535                       
     536                        break;
     537                case AF_INET6:
     538                        addr6.sin6_port = host2uint16_t_be(rsock->port);
     539                       
     540                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read receive");
     541                        if (!async_data_read_receive(&rcallid, &addr_length)) {
     542                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     543                                fibril_mutex_unlock(&socket->lock);
     544                                async_answer_0(callid, EINVAL);
     545                                return;
     546                        }
     547                       
     548                        if (addr_length > sizeof(addr6))
     549                                addr_length = sizeof(addr6);
     550                       
     551                        addr_size = sizeof(addr6);
     552                       
     553                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read finalize");
     554                        rc = async_data_read_finalize(rcallid, &addr6, addr_length);
     555                        if (rc != EOK) {
     556                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     557                                fibril_mutex_unlock(&socket->lock);
     558                                async_answer_0(callid, EINVAL);
     559                                return;
     560                        }
     561                       
     562                        break;
     563                default:
     564                        fibril_mutex_unlock(&socket->recv_buffer_lock);
    453565                        fibril_mutex_unlock(&socket->lock);
    454566                        async_answer_0(callid, EINVAL);
    455567                        return;
    456568                }
    457 
    458                 if (addr_length > sizeof(addr))
    459                         addr_length = sizeof(addr);
    460 
    461                 log_msg(LVL_DEBUG, "addr read finalize");
    462                 rc = async_data_read_finalize(rcallid, &addr, addr_length);
    463                 if (rc != EOK) {
    464                         fibril_mutex_unlock(&socket->lock);
    465                         async_answer_0(callid, EINVAL);
    466                         return;
    467                 }
    468         }
    469 
    470         log_msg(LVL_DEBUG, "data read receive");
     569        }
     570       
     571        log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive");
     572       
     573        size_t length;
    471574        if (!async_data_read_receive(&rcallid, &length)) {
     575                fibril_mutex_unlock(&socket->recv_buffer_lock);
    472576                fibril_mutex_unlock(&socket->lock);
    473577                async_answer_0(callid, EINVAL);
    474578                return;
    475579        }
    476 
     580       
    477581        if (length > data_len)
    478582                length = data_len;
    479 
    480         log_msg(LVL_DEBUG, "data read finalize");
    481         rc = async_data_read_finalize(rcallid, buffer, length);
    482 
    483         if (length < data_len && rc == EOK)
     583       
     584        log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize");
     585       
     586        rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
     587       
     588        if ((length < data_len) && (rc == EOK))
    484589                rc = EOVERFLOW;
    485 
    486         log_msg(LVL_DEBUG, "read_data_length <- %zu", length);
     590       
     591        log_msg(LOG_DEFAULT, LVL_DEBUG, "read_data_length <- %zu", length);
     592       
     593        ipc_call_t answer;
     594       
     595        IPC_SET_ARG2(answer, 0);
    487596        SOCKET_SET_READ_DATA_LENGTH(answer, length);
    488         SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(addr));
    489         answer_call(callid, EOK, &answer, 3);
    490 
    491         /* Push one fragment notification to client's queue */
    492         udp_sock_notify_data(sock_core);
     597        SOCKET_SET_ADDRESS_LENGTH(answer, addr_size);
     598        async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
     599            IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
     600       
     601        socket->recv_buffer_used = 0;
     602       
     603        fibril_condvar_broadcast(&socket->recv_buffer_cv);
     604        fibril_mutex_unlock(&socket->recv_buffer_lock);
    493605        fibril_mutex_unlock(&socket->lock);
    494606}
     
    496608static void udp_sock_close(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    497609{
    498         int socket_id;
    499         socket_core_t *sock_core;
    500         udp_sockdata_t *socket;
    501         int rc;
    502 
    503         log_msg(LVL_DEBUG, "tcp_sock_close()");
    504         socket_id = SOCKET_GET_SOCKET_ID(call);
    505 
    506         sock_core = socket_cores_find(&client->sockets, socket_id);
     610        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close()");
     611        int socket_id = SOCKET_GET_SOCKET_ID(call);
     612
     613        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - find core");
     614        socket_core_t *sock_core =
     615            socket_cores_find(&client->sockets, socket_id);
    507616        if (sock_core == NULL) {
     617        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - core not found");
    508618                async_answer_0(callid, ENOTSOCK);
    509619                return;
    510620        }
    511621
    512         socket = (udp_sockdata_t *)sock_core->specific_data;
     622        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - spec data");
     623        udp_sockdata_t *socket =
     624            (udp_sockdata_t *) sock_core->specific_data;
     625        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - lock socket");
    513626        fibril_mutex_lock(&socket->lock);
    514627
    515         assert(socket->assoc != NULL);
    516         udp_uc_destroy(socket->assoc);
    517 
    518         rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock,
     628        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close() - lock socket buffer");
     629        fibril_mutex_lock(&socket->recv_buffer_lock);
     630        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_close - set socket->sock_core = NULL");
     631        socket->sock_core = NULL;
     632        fibril_mutex_unlock(&socket->recv_buffer_lock);
     633
     634        udp_uc_reset(socket->assoc);
     635
     636        int rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock,
    519637            udp_free_sock_data);
    520638        if (rc != EOK) {
     639                log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_close - socket_destroy failed");
    521640                fibril_mutex_unlock(&socket->lock);
    522641                async_answer_0(callid, rc);
     
    524643        }
    525644
     645        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_close - broadcast recv_buffer_cv");
     646        fibril_condvar_broadcast(&socket->recv_buffer_cv);
     647
    526648        fibril_mutex_unlock(&socket->lock);
    527649        async_answer_0(callid, EOK);
     
    530652static void udp_sock_getsockopt(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    531653{
    532         log_msg(LVL_DEBUG, "udp_sock_getsockopt()");
     654        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_getsockopt()");
    533655        async_answer_0(callid, ENOTSUP);
    534656}
     
    536658static void udp_sock_setsockopt(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    537659{
    538         log_msg(LVL_DEBUG, "udp_sock_setsockopt()");
     660        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_setsockopt()");
    539661        async_answer_0(callid, ENOTSUP);
     662}
     663
     664static int udp_sock_recv_fibril(void *arg)
     665{
     666        udp_sockdata_t *sock = (udp_sockdata_t *)arg;
     667        udp_error_t urc;
     668        xflags_t xflags;
     669        size_t rcvd;
     670
     671        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril()");
     672
     673        fibril_mutex_lock(&sock->recv_buffer_lock);
     674
     675        while (true) {
     676                log_msg(LOG_DEFAULT, LVL_DEBUG, "[] wait for rcv buffer empty()");
     677                while ((sock->recv_buffer_used != 0) && (sock->sock_core != NULL)) {
     678                        fibril_condvar_wait(&sock->recv_buffer_cv,
     679                            &sock->recv_buffer_lock);
     680                }
     681
     682                fibril_mutex_unlock(&sock->recv_buffer_lock);
     683
     684                log_msg(LOG_DEFAULT, LVL_DEBUG, "[] call udp_uc_receive()");
     685                urc = udp_uc_receive(sock->assoc, sock->recv_buffer,
     686                    UDP_FRAGMENT_SIZE, &rcvd, &xflags, &sock->recv_fsock);
     687                fibril_mutex_lock(&sock->recv_buffer_lock);
     688                sock->recv_error = urc;
     689
     690                log_msg(LOG_DEFAULT, LVL_DEBUG, "[] udp_uc_receive -> %d", urc);
     691
     692                if (sock->sock_core != NULL)
     693                        udp_sock_notify_data(sock->sock_core);
     694
     695                if (urc != UDP_EOK) {
     696                        log_msg(LOG_DEFAULT, LVL_DEBUG, "[] urc != UDP_EOK, break");
     697                        fibril_condvar_broadcast(&sock->recv_buffer_cv);
     698                        fibril_mutex_unlock(&sock->recv_buffer_lock);
     699                        break;
     700                }
     701
     702                log_msg(LOG_DEFAULT, LVL_DEBUG, "[] got data - broadcast recv_buffer_cv");
     703
     704                sock->recv_buffer_used = rcvd;
     705                fibril_condvar_broadcast(&sock->recv_buffer_cv);
     706        }
     707
     708        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril() exited loop");
     709        fibril_mutex_unlock(&sock->recv_buffer_lock);
     710        udp_uc_destroy(sock->assoc);
     711
     712        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril() terminated");
     713
     714        return 0;
    540715}
    541716
     
    553728
    554729        while (true) {
    555                 log_msg(LVL_DEBUG, "udp_sock_connection: wait");
     730                log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connection: wait");
    556731                callid = async_get_call(&call);
    557732                if (!IPC_GET_IMETHOD(call))
    558733                        break;
    559734
    560                 log_msg(LVL_DEBUG, "udp_sock_connection: METHOD=%d",
     735                log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connection: METHOD=%d",
    561736                    (int)IPC_GET_IMETHOD(call));
    562737
     
    599774                }
    600775        }
     776
     777        /* Clean up */
     778        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connection: Clean up");
     779        async_hangup(client.sess);
     780        socket_cores_release(NULL, &client.sockets, &gsock, udp_free_sock_data);
    601781}
    602782
Note: See TracChangeset for help on using the changeset viewer.