Changeset 02a09ed in mainline for uspace/srv/net/udp/sock.c


Ignore:
Timestamp:
2013-06-28T20:20:03Z (11 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1d24ad3
Parents:
edf0d27
Message:

add basic infrastructure for IPv6 (inactive)
make inet_addr_t a universal address type

File:
1 edited

Legend:

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

    redf0d27 r02a09ed  
    159159static void udp_sock_bind(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    160160{
    161         int rc;
    162         struct sockaddr_in *addr;
    163         size_t addr_size;
    164         socket_core_t *sock_core;
    165         udp_sockdata_t *socket;
    166         udp_sock_t fsock;
    167         udp_error_t urc;
    168 
    169161        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_bind()");
    170162        log_msg(LOG_DEFAULT, LVL_DEBUG, " - async_data_write_accept");
    171 
    172         addr = NULL;
    173 
    174         rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_size);
     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);
    175167        if (rc != EOK) {
    176168                async_answer_0(callid, rc);
    177                 goto out;
    178         }
    179        
    180         if (addr_size != sizeof(struct sockaddr_in)) {
     169                return;
     170        }
     171       
     172        if ((addr_len != sizeof(struct sockaddr_in)) &&
     173            (addr_len != sizeof(struct sockaddr_in6))) {
    181174                async_answer_0(callid, EINVAL);
    182175                goto out;
    183176        }
    184177       
     178        struct sockaddr_in *addr = (struct sockaddr_in *) addr6;
     179       
    185180        log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_bind");
     181       
    186182        rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
    187             addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
     183            addr6, addr_len, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
    188184            last_used_port);
    189185        if (rc != EOK) {
     
    193189       
    194190        log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_cores_find");
    195         sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call));
     191       
     192        socket_core_t *sock_core = socket_cores_find(&client->sockets,
     193            SOCKET_GET_SOCKET_ID(call));
    196194        if (sock_core == NULL) {
    197195                async_answer_0(callid, ENOENT);
    198196                goto out;
    199197        }
    200 
    201         socket = (udp_sockdata_t *) sock_core->specific_data;
    202        
    203         inet_addr_unpack(uint32_t_be2host(addr->sin_addr.s_addr),
    204             &fsock.addr);
    205         fsock.port = sock_core->port;
    206         urc = udp_uc_set_local(socket->assoc, &fsock);
    207 
     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       
    208220        switch (urc) {
    209221        case UDP_EOK:
     
    225237        log_msg(LOG_DEFAULT, LVL_DEBUG, " - success");
    226238        async_answer_0(callid, rc);
     239       
    227240out:
    228         if (addr != NULL)
    229                 free(addr);
     241        if (addr6 != NULL)
     242                free(addr6);
    230243}
    231244
     
    252265        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_send()");
    253266       
    254         struct sockaddr_in *addr = NULL;
    255         udp_sock_t fsock;
    256         udp_sock_t *fsock_ptr;
     267        struct sockaddr_in6 *addr6 = NULL;
     268        struct sockaddr_in *addr;
     269        udp_sock_t fsocket;
     270        udp_sock_t *fsocket_ptr;
    257271       
    258272        if (IPC_GET_IMETHOD(call) == NET_SOCKET_SENDTO) {
    259                 size_t addr_size;
    260                 int rc = async_data_write_accept((void **) &addr, false,
    261                     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);
    262276                if (rc != EOK) {
    263277                        async_answer_0(callid, rc);
    264                         goto out;
    265                 }
    266                
    267                 if (addr_size != sizeof(struct sockaddr_in)) {
     278                        return;
     279                }
     280               
     281                if ((addr_len != sizeof(struct sockaddr_in)) &&
     282                    (addr_len != sizeof(struct sockaddr_in6))) {
    268283                        async_answer_0(callid, EINVAL);
    269284                        goto out;
    270285                }
    271286               
    272                 inet_addr_unpack(uint32_t_be2host(addr->sin_addr.s_addr),
    273                     &fsock.addr);
    274                 fsock.port = uint16_t_be2host(addr->sin_port);
    275                 fsock_ptr = &fsock;
     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;
    276303        } else
    277                 fsock_ptr = NULL;
     304                fsocket_ptr = NULL;
    278305       
    279306        int socket_id = SOCKET_GET_SOCKET_ID(call);
     
    321348                inet_addr_t rem_addr;
    322349               
    323                 rem_addr = fsock_ptr ? fsock.addr :
     350                rem_addr = fsocket_ptr ? fsocket.addr :
    324351                    socket->assoc->ident.foreign.addr;
    325352               
     
    361388               
    362389                udp_error_t urc =
    363                     udp_uc_send(socket->assoc, fsock_ptr, buffer, length, 0);
     390                    udp_uc_send(socket->assoc, fsocket_ptr, buffer, length, 0);
    364391               
    365392                switch (urc) {
     
    396423       
    397424out:
    398         if (addr != NULL)
    399                 free(addr);
     425        if (addr6 != NULL)
     426                free(addr6);
    400427}
    401428
    402429static void udp_sock_recvfrom(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    403430{
    404         int socket_id;
    405         int flags;
    406         size_t addr_length, length;
    407         socket_core_t *sock_core;
    408         udp_sockdata_t *socket;
    409         ipc_call_t answer;
    410         ipc_callid_t rcallid;
    411         size_t data_len;
    412         udp_error_t urc;
    413         udp_sock_t *rsock;
    414         struct sockaddr_in addr;
    415         int rc;
    416 
    417431        log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: udp_sock_recv[from]()", client);
    418 
    419         socket_id = SOCKET_GET_SOCKET_ID(call);
    420         flags = SOCKET_GET_FLAGS(call);
    421 
    422         sock_core = socket_cores_find(&client->sockets, socket_id);
     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);
    423437        if (sock_core == NULL) {
    424438                async_answer_0(callid, ENOTSOCK);
    425439                return;
    426440        }
    427 
    428         socket = (udp_sockdata_t *)sock_core->specific_data;
     441       
     442        udp_sockdata_t *socket =
     443            (udp_sockdata_t *) sock_core->specific_data;
     444       
    429445        fibril_mutex_lock(&socket->lock);
    430446       
     
    434450                return;
    435451        }
    436 
    437         (void)flags;
    438 
     452       
    439453        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): lock recv_buffer lock");
     454       
    440455        fibril_mutex_lock(&socket->recv_buffer_lock);
    441         while (socket->recv_buffer_used == 0 && socket->recv_error == UDP_EOK) {
     456       
     457        while ((socket->recv_buffer_used == 0) &&
     458            (socket->recv_error == UDP_EOK)) {
    442459                log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): wait for cv");
    443460                fibril_condvar_wait(&socket->recv_buffer_cv,
     
    446463       
    447464        log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer");
    448 
    449         rsock = &socket->recv_fsock;
    450         data_len = socket->recv_buffer_used;
    451         urc = socket->recv_error;
    452 
     465       
     466        size_t data_len = socket->recv_buffer_used;
     467        udp_error_t urc = socket->recv_error;
     468       
    453469        log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv data_len=%zu", data_len);
    454 
     470       
     471        int rc;
     472       
    455473        switch (urc) {
    456474        case UDP_EOK:
     
    476494                return;
    477495        }
    478 
     496       
     497        ipc_callid_t rcallid;
     498        size_t addr_size = 0;
     499       
    479500        if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) {
    480501                /* Fill address */
    481                 uint32_t rsock_addr;
    482                 int rc = inet_addr_pack(&rsock->addr, &rsock_addr);
    483                 if (rc != EOK) {
    484                         fibril_mutex_unlock(&socket->recv_buffer_lock);
    485                         fibril_mutex_unlock(&socket->lock);
    486                         async_answer_0(callid, rc);
    487                         return;
    488                 }
    489                
    490                 addr.sin_family = AF_INET;
    491                 addr.sin_addr.s_addr = host2uint32_t_be(rsock_addr);
    492                 addr.sin_port = host2uint16_t_be(rsock->port);
    493 
    494                 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
    495                 if (!async_data_read_receive(&rcallid, &addr_length)) {
     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:
    496564                        fibril_mutex_unlock(&socket->recv_buffer_lock);
    497565                        fibril_mutex_unlock(&socket->lock);
     
    499567                        return;
    500568                }
    501 
    502                 if (addr_length > sizeof(addr))
    503                         addr_length = sizeof(addr);
    504 
    505                 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
    506                 rc = async_data_read_finalize(rcallid, &addr, addr_length);
    507                 if (rc != EOK) {
    508                         fibril_mutex_unlock(&socket->recv_buffer_lock);
    509                         fibril_mutex_unlock(&socket->lock);
    510                         async_answer_0(callid, EINVAL);
    511                         return;
    512                 }
    513         }
    514 
     569        }
     570       
    515571        log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive");
     572       
     573        size_t length;
    516574        if (!async_data_read_receive(&rcallid, &length)) {
    517575                fibril_mutex_unlock(&socket->recv_buffer_lock);
     
    525583       
    526584        log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize");
     585       
    527586        rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
    528 
    529         if (length < data_len && rc == EOK)
     587       
     588        if ((length < data_len) && (rc == EOK))
    530589                rc = EOVERFLOW;
    531590       
    532591        log_msg(LOG_DEFAULT, LVL_DEBUG, "read_data_length <- %zu", length);
     592       
     593        ipc_call_t answer;
     594       
    533595        IPC_SET_ARG2(answer, 0);
    534596        SOCKET_SET_READ_DATA_LENGTH(answer, length);
    535         SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(addr));
     597        SOCKET_SET_ADDRESS_LENGTH(answer, addr_size);
    536598        async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
    537599            IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
     
    634696                        log_msg(LOG_DEFAULT, LVL_DEBUG, "[] urc != UDP_EOK, break");
    635697                        fibril_condvar_broadcast(&sock->recv_buffer_cv);
     698                        fibril_mutex_unlock(&sock->recv_buffer_lock);
    636699                        break;
    637700                }
Note: See TracChangeset for help on using the changeset viewer.