Ignore:
File:
1 edited

Legend:

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

    rccb5165 rf4a27304  
    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         fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
    204         fsock.port = sock_core->port;
    205         urc = udp_uc_set_local(socket->assoc, &fsock);
    206 
     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       
    207220        switch (urc) {
    208221        case UDP_EOK:
     
    221234                assert(false);
    222235        }
    223 
     236       
    224237        log_msg(LOG_DEFAULT, LVL_DEBUG, " - success");
    225238        async_answer_0(callid, rc);
     239       
    226240out:
    227         if (addr != NULL)
    228                 free(addr);
     241        if (addr6 != NULL)
     242                free(addr6);
    229243}
    230244
     
    251265        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_send()");
    252266       
    253         struct sockaddr_in *addr = NULL;
    254         udp_sock_t fsock;
    255         udp_sock_t *fsock_ptr;
     267        uint8_t *buffer = calloc(UDP_FRAGMENT_SIZE, 1);
     268        if (buffer == NULL) {
     269                async_answer_0(callid, ENOMEM);
     270                return;
     271        }
     272       
     273        struct sockaddr_in6 *addr6 = NULL;
     274        struct sockaddr_in *addr;
     275        udp_sock_t fsocket;
     276        udp_sock_t *fsocket_ptr;
    256277       
    257278        if (IPC_GET_IMETHOD(call) == NET_SOCKET_SENDTO) {
    258                 size_t addr_size;
    259                 int rc = async_data_write_accept((void **) &addr, false,
    260                     0, 0, 0, &addr_size);
     279                size_t addr_len;
     280                int rc = async_data_write_accept((void **) &addr6, false,
     281                    0, 0, 0, &addr_len);
    261282                if (rc != EOK) {
    262283                        async_answer_0(callid, rc);
     
    264285                }
    265286               
    266                 if (addr_size != sizeof(struct sockaddr_in)) {
     287                if ((addr_len != sizeof(struct sockaddr_in)) &&
     288                    (addr_len != sizeof(struct sockaddr_in6))) {
    267289                        async_answer_0(callid, EINVAL);
    268290                        goto out;
    269291                }
    270292               
    271                 fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
    272                 fsock.port = uint16_t_be2host(addr->sin_port);
    273                 fsock_ptr = &fsock;
     293                addr = (struct sockaddr_in *) addr6;
     294               
     295                switch (addr->sin_family) {
     296                case AF_INET:
     297                        inet_sockaddr_in_addr(addr, &fsocket.addr);
     298                        break;
     299                case AF_INET6:
     300                        inet_sockaddr_in6_addr(addr6, &fsocket.addr);
     301                        break;
     302                default:
     303                        async_answer_0(callid, EINVAL);
     304                        goto out;
     305                }
     306               
     307                fsocket.port = uint16_t_be2host(addr->sin_port);
     308                fsocket_ptr = &fsocket;
    274309        } else
    275                 fsock_ptr = NULL;
     310                fsocket_ptr = NULL;
    276311       
    277312        int socket_id = SOCKET_GET_SOCKET_ID(call);
     
    314349        fibril_mutex_lock(&socket->lock);
    315350       
    316         if (socket->assoc->ident.local.addr.ipv4 == UDP_IPV4_ANY) {
     351        if (inet_addr_is_any(&socket->assoc->ident.local.addr)) {
    317352                /* Determine local IP address */
    318                 inet_addr_t loc_addr, rem_addr;
    319                
    320                 rem_addr.ipv4 = fsock_ptr ? fsock.addr.ipv4 :
    321                     socket->assoc->ident.foreign.addr.ipv4;
     353                inet_addr_t loc_addr;
     354                inet_addr_t rem_addr;
     355               
     356                rem_addr = fsocket_ptr ? fsocket.addr :
     357                    socket->assoc->ident.foreign.addr;
    322358               
    323359                int rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
     
    327363                        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_sendto: Failed to "
    328364                            "determine local address.");
    329                         return;
    330                 }
    331                
    332                 socket->assoc->ident.local.addr.ipv4 = loc_addr.ipv4;
    333                 log_msg(LOG_DEFAULT, LVL_DEBUG, "Local IP address is %x",
    334                     socket->assoc->ident.local.addr.ipv4);
     365                        goto out;
     366                }
     367               
     368                socket->assoc->ident.local.addr = loc_addr;
    335369        }
    336370       
     
    351385                        length = UDP_FRAGMENT_SIZE;
    352386               
    353                 uint8_t buffer[UDP_FRAGMENT_SIZE];
    354387                int rc = async_data_write_finalize(wcallid, buffer, length);
    355388                if (rc != EOK) {
     
    360393               
    361394                udp_error_t urc =
    362                     udp_uc_send(socket->assoc, fsock_ptr, buffer, length, 0);
     395                    udp_uc_send(socket->assoc, fsocket_ptr, buffer, length, 0);
    363396               
    364397                switch (urc) {
     
    395428       
    396429out:
    397         if (addr != NULL)
    398                 free(addr);
     430        if (addr6 != NULL)
     431                free(addr6);
     432       
     433        free(buffer);
    399434}
    400435
    401436static void udp_sock_recvfrom(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    402437{
    403         int socket_id;
    404         int flags;
    405         size_t addr_length, length;
    406         socket_core_t *sock_core;
    407         udp_sockdata_t *socket;
    408         ipc_call_t answer;
    409         ipc_callid_t rcallid;
    410         size_t data_len;
    411         udp_error_t urc;
    412         udp_sock_t rsock;
    413         struct sockaddr_in addr;
    414         int rc;
    415 
    416438        log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: udp_sock_recv[from]()", client);
    417 
    418         socket_id = SOCKET_GET_SOCKET_ID(call);
    419         flags = SOCKET_GET_FLAGS(call);
    420 
    421         sock_core = socket_cores_find(&client->sockets, socket_id);
     439       
     440        int socket_id = SOCKET_GET_SOCKET_ID(call);
     441       
     442        socket_core_t *sock_core =
     443            socket_cores_find(&client->sockets, socket_id);
    422444        if (sock_core == NULL) {
    423445                async_answer_0(callid, ENOTSOCK);
    424446                return;
    425447        }
    426 
    427         socket = (udp_sockdata_t *)sock_core->specific_data;
     448       
     449        udp_sockdata_t *socket =
     450            (udp_sockdata_t *) sock_core->specific_data;
     451       
    428452        fibril_mutex_lock(&socket->lock);
    429 
     453       
    430454        if (socket->assoc == NULL) {
    431455                fibril_mutex_unlock(&socket->lock);
     
    433457                return;
    434458        }
    435 
    436         (void)flags;
    437 
     459       
    438460        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): lock recv_buffer lock");
     461       
    439462        fibril_mutex_lock(&socket->recv_buffer_lock);
    440         while (socket->recv_buffer_used == 0 && socket->recv_error == UDP_EOK) {
     463       
     464        while ((socket->recv_buffer_used == 0) &&
     465            (socket->recv_error == UDP_EOK)) {
    441466                log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): wait for cv");
    442467                fibril_condvar_wait(&socket->recv_buffer_cv,
    443468                    &socket->recv_buffer_lock);
    444469        }
    445 
     470       
    446471        log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer");
    447 
    448         rsock = socket->recv_fsock;
    449         data_len = socket->recv_buffer_used;
    450         urc = socket->recv_error;
    451 
     472       
     473        size_t data_len = socket->recv_buffer_used;
     474        udp_error_t urc = socket->recv_error;
     475       
    452476        log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv data_len=%zu", data_len);
    453 
     477       
     478        int rc;
     479       
    454480        switch (urc) {
    455481        case UDP_EOK:
     
    466492                assert(false);
    467493        }
    468 
     494       
    469495        log_msg(LOG_DEFAULT, LVL_DEBUG, "**** udp_uc_receive -> %d", rc);
     496       
    470497        if (rc != EOK) {
    471498                fibril_mutex_unlock(&socket->recv_buffer_lock);
     
    474501                return;
    475502        }
    476 
     503       
     504        ipc_callid_t rcallid;
     505        size_t addr_size = 0;
     506       
    477507        if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) {
    478                 /* Fill addr */
    479                 addr.sin_family = AF_INET;
    480                 addr.sin_addr.s_addr = host2uint32_t_be(rsock.addr.ipv4);
    481                 addr.sin_port = host2uint16_t_be(rsock.port);
    482 
    483                 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
    484                 if (!async_data_read_receive(&rcallid, &addr_length)) {
     508                /* Fill address */
     509                udp_sock_t *rsock = &socket->recv_fsock;
     510                struct sockaddr_in addr;
     511                struct sockaddr_in6 addr6;
     512                size_t addr_length;
     513               
     514                uint16_t addr_af = inet_addr_sockaddr_in(&rsock->addr, &addr,
     515                    &addr6);
     516               
     517                switch (addr_af) {
     518                case AF_INET:
     519                        addr.sin_port = host2uint16_t_be(rsock->port);
     520                       
     521                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
     522                        if (!async_data_read_receive(&rcallid, &addr_length)) {
     523                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     524                                fibril_mutex_unlock(&socket->lock);
     525                                async_answer_0(callid, EINVAL);
     526                                return;
     527                        }
     528                       
     529                        if (addr_length > sizeof(addr))
     530                                addr_length = sizeof(addr);
     531                       
     532                        addr_size = sizeof(addr);
     533                       
     534                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
     535                        rc = async_data_read_finalize(rcallid, &addr, addr_length);
     536                        if (rc != EOK) {
     537                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     538                                fibril_mutex_unlock(&socket->lock);
     539                                async_answer_0(callid, EINVAL);
     540                                return;
     541                        }
     542                       
     543                        break;
     544                case AF_INET6:
     545                        addr6.sin6_port = host2uint16_t_be(rsock->port);
     546                       
     547                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read receive");
     548                        if (!async_data_read_receive(&rcallid, &addr_length)) {
     549                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     550                                fibril_mutex_unlock(&socket->lock);
     551                                async_answer_0(callid, EINVAL);
     552                                return;
     553                        }
     554                       
     555                        if (addr_length > sizeof(addr6))
     556                                addr_length = sizeof(addr6);
     557                       
     558                        addr_size = sizeof(addr6);
     559                       
     560                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read finalize");
     561                        rc = async_data_read_finalize(rcallid, &addr6, addr_length);
     562                        if (rc != EOK) {
     563                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     564                                fibril_mutex_unlock(&socket->lock);
     565                                async_answer_0(callid, EINVAL);
     566                                return;
     567                        }
     568                       
     569                        break;
     570                default:
    485571                        fibril_mutex_unlock(&socket->recv_buffer_lock);
    486572                        fibril_mutex_unlock(&socket->lock);
     
    488574                        return;
    489575                }
    490 
    491                 if (addr_length > sizeof(addr))
    492                         addr_length = sizeof(addr);
    493 
    494                 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
    495                 rc = async_data_read_finalize(rcallid, &addr, addr_length);
    496                 if (rc != EOK) {
    497                         fibril_mutex_unlock(&socket->recv_buffer_lock);
    498                         fibril_mutex_unlock(&socket->lock);
    499                         async_answer_0(callid, EINVAL);
    500                         return;
    501                 }
    502         }
    503 
     576        }
     577       
    504578        log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive");
     579       
     580        size_t length;
    505581        if (!async_data_read_receive(&rcallid, &length)) {
    506582                fibril_mutex_unlock(&socket->recv_buffer_lock);
     
    509585                return;
    510586        }
    511 
     587       
    512588        if (length > data_len)
    513589                length = data_len;
    514 
     590       
    515591        log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize");
     592       
    516593        rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
    517 
    518         if (length < data_len && rc == EOK)
     594       
     595        if ((length < data_len) && (rc == EOK))
    519596                rc = EOVERFLOW;
    520 
     597       
    521598        log_msg(LOG_DEFAULT, LVL_DEBUG, "read_data_length <- %zu", length);
     599       
     600        ipc_call_t answer;
     601       
    522602        IPC_SET_ARG2(answer, 0);
    523603        SOCKET_SET_READ_DATA_LENGTH(answer, length);
    524         SOCKET_SET_ADDRESS_LENGTH(answer, sizeof(addr));
     604        SOCKET_SET_ADDRESS_LENGTH(answer, addr_size);
    525605        async_answer_3(callid, EOK, IPC_GET_ARG1(answer),
    526606            IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
    527 
     607       
    528608        socket->recv_buffer_used = 0;
    529 
     609       
    530610        fibril_condvar_broadcast(&socket->recv_buffer_cv);
    531611        fibril_mutex_unlock(&socket->recv_buffer_lock);
     
    602682        while (true) {
    603683                log_msg(LOG_DEFAULT, LVL_DEBUG, "[] wait for rcv buffer empty()");
    604                 while (sock->recv_buffer_used != 0 && sock->sock_core != NULL) {
     684                while ((sock->recv_buffer_used != 0) && (sock->sock_core != NULL)) {
    605685                        fibril_condvar_wait(&sock->recv_buffer_cv,
    606686                            &sock->recv_buffer_lock);
     
    623703                        log_msg(LOG_DEFAULT, LVL_DEBUG, "[] urc != UDP_EOK, break");
    624704                        fibril_condvar_broadcast(&sock->recv_buffer_cv);
     705                        fibril_mutex_unlock(&sock->recv_buffer_lock);
    625706                        break;
    626707                }
Note: See TracChangeset for help on using the changeset viewer.