Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 451481c8 in mainline


Ignore:
Timestamp:
2013-03-14T12:15:24Z (9 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
3ca2e36
Parents:
8fc8969
Message:

properly implement the implicit binding of a socket to a port

Location:
uspace/srv/net/udp
Files:
5 edited

Legend:

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

    r8fc8969 r451481c8  
    200200/** Set local socket in association.
    201201 *
    202  * @param assoc         Association
    203  * @param fsock         Foreign socket (deeply copied)
     202 * @param assoc Association
     203 * @param lsock Local socket (deeply copied)
     204 *
    204205 */
    205206void udp_assoc_set_local(udp_assoc_t *assoc, udp_sock_t *lsock)
     
    208209        fibril_mutex_lock(&assoc->lock);
    209210        assoc->ident.local = *lsock;
     211        fibril_mutex_unlock(&assoc->lock);
     212}
     213
     214/** Set local port in association.
     215 *
     216 * @param assoc Association
     217 * @param lport Local port
     218 *
     219 */
     220void udp_assoc_set_local_port(udp_assoc_t *assoc, uint16_t lport)
     221{
     222        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_set_local(%p, %" PRIu16 ")", assoc, lport);
     223        fibril_mutex_lock(&assoc->lock);
     224        assoc->ident.local.port = lport;
    210225        fibril_mutex_unlock(&assoc->lock);
    211226}
  • uspace/srv/net/udp/assoc.h

    r8fc8969 r451481c8  
    4747extern void udp_assoc_set_foreign(udp_assoc_t *, udp_sock_t *);
    4848extern void udp_assoc_set_local(udp_assoc_t *, udp_sock_t *);
     49extern void udp_assoc_set_local_port(udp_assoc_t *, uint16_t);
    4950extern int udp_assoc_send(udp_assoc_t *, udp_sock_t *, udp_msg_t *);
    5051extern int udp_assoc_recv(udp_assoc_t *, udp_msg_t **, udp_sock_t *);
  • uspace/srv/net/udp/sock.c

    r8fc8969 r451481c8  
    249249static void udp_sock_sendto(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    250250{
    251         int socket_id;
    252         int fragments;
    253         int index;
    254         struct sockaddr_in *addr;
    255         size_t addr_size;
    256         socket_core_t *sock_core;
    257         udp_sockdata_t *socket;
    258         udp_sock_t fsock, *fsockp;
    259         ipc_call_t answer;
    260         ipc_callid_t wcallid;
    261         size_t length;
    262         uint8_t buffer[UDP_FRAGMENT_SIZE];
    263         udp_error_t urc;
    264         int rc;
    265 
    266251        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_send()");
    267 
    268         addr = NULL;
    269 
     252       
     253        struct sockaddr_in *addr = NULL;
     254        udp_sock_t fsock;
     255        udp_sock_t *fsock_ptr;
     256       
    270257        if (IPC_GET_IMETHOD(call) == NET_SOCKET_SENDTO) {
    271                 rc = async_data_write_accept((void **) &addr, false,
     258                size_t addr_size;
     259                int rc = async_data_write_accept((void **) &addr, false,
    272260                    0, 0, 0, &addr_size);
    273261                if (rc != EOK) {
     
    275263                        goto out;
    276264                }
    277 
     265               
    278266                if (addr_size != sizeof(struct sockaddr_in)) {
    279267                        async_answer_0(callid, EINVAL);
    280268                        goto out;
    281269                }
    282 
     270               
    283271                fsock.addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
    284272                fsock.port = uint16_t_be2host(addr->sin_port);
    285                 fsockp = &fsock;
    286         } else {
    287                 fsockp = NULL;
    288         }
    289 
    290         socket_id = SOCKET_GET_SOCKET_ID(call);
    291         fragments = SOCKET_GET_DATA_FRAGMENTS(call);
     273                fsock_ptr = &fsock;
     274        } else
     275                fsock_ptr = NULL;
     276       
     277        int socket_id = SOCKET_GET_SOCKET_ID(call);
     278       
    292279        SOCKET_GET_FLAGS(call);
    293 
    294         sock_core = socket_cores_find(&client->sockets, socket_id);
     280       
     281        socket_core_t *sock_core =
     282            socket_cores_find(&client->sockets, socket_id);
    295283        if (sock_core == NULL) {
    296284                async_answer_0(callid, ENOTSOCK);
    297285                goto out;
    298286        }
    299 
    300         if (sock_core->port == 0) {
     287       
     288        udp_sockdata_t *socket =
     289            (udp_sockdata_t *) sock_core->specific_data;
     290       
     291        if ((sock_core->port == 0) || (sock_core->port == -1)) {
    301292                /* Implicitly bind socket to port */
    302                 rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
    303                     addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
    304                     last_used_port);
     293                int rc = socket_bind_free_port(&gsock, sock_core,
     294                    UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, last_used_port);
    305295                if (rc != EOK) {
    306296                        async_answer_0(callid, rc);
    307297                        goto out;
    308298                }
    309         }
    310 
    311         socket = (udp_sockdata_t *)sock_core->specific_data;
     299               
     300                assert(sock_core->port > 0);
     301                udp_error_t urc = udp_uc_set_local_port(socket->assoc,
     302                    sock_core->port);
     303               
     304                if (urc != UDP_EOK) {
     305                        // TODO: better error handling
     306                        async_answer_0(callid, EINTR);
     307                        goto out;
     308                }
     309        }
     310       
    312311        fibril_mutex_lock(&socket->lock);
    313 
     312       
    314313        if (socket->assoc->ident.local.addr.ipv4 == UDP_IPV4_ANY) {
    315314                /* Determine local IP address */
    316315                inet_addr_t loc_addr, rem_addr;
    317 
    318                 rem_addr.ipv4 = fsockp ? fsock.addr.ipv4 :
     316               
     317                rem_addr.ipv4 = fsock_ptr ? fsock.addr.ipv4 :
    319318                    socket->assoc->ident.foreign.addr.ipv4;
    320 
    321                 rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
     319               
     320                int rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
    322321                if (rc != EOK) {
    323322                        fibril_mutex_unlock(&socket->lock);
     
    327326                        return;
    328327                }
    329 
     328               
    330329                socket->assoc->ident.local.addr.ipv4 = loc_addr.ipv4;
    331330                log_msg(LOG_DEFAULT, LVL_DEBUG, "Local IP address is %x",
    332331                    socket->assoc->ident.local.addr.ipv4);
    333332        }
    334 
    335 
     333       
    336334        assert(socket->assoc != NULL);
    337 
    338         for (index = 0; index < fragments; index++) {
     335       
     336        int fragments = SOCKET_GET_DATA_FRAGMENTS(call);
     337        for (int index = 0; index < fragments; index++) {
     338                ipc_callid_t wcallid;
     339                size_t length;
     340               
    339341                if (!async_data_write_receive(&wcallid, &length)) {
    340342                        fibril_mutex_unlock(&socket->lock);
     
    342344                        goto out;
    343345                }
    344 
     346               
    345347                if (length > UDP_FRAGMENT_SIZE)
    346348                        length = UDP_FRAGMENT_SIZE;
    347 
    348                 rc = async_data_write_finalize(wcallid, buffer, length);
     349               
     350                uint8_t buffer[UDP_FRAGMENT_SIZE];
     351                int rc = async_data_write_finalize(wcallid, buffer, length);
    349352                if (rc != EOK) {
    350353                        fibril_mutex_unlock(&socket->lock);
     
    352355                        goto out;
    353356                }
    354 
    355                 urc = udp_uc_send(socket->assoc, fsockp, buffer, length, 0);
    356 
     357               
     358                udp_error_t urc =
     359                    udp_uc_send(socket->assoc, fsock_ptr, buffer, length, 0);
     360               
    357361                switch (urc) {
    358362                case UDP_EOK:
     
    371375                        assert(false);
    372376                }
    373 
     377               
    374378                if (rc != EOK) {
    375379                        fibril_mutex_unlock(&socket->lock);
     
    378382                }
    379383        }
     384       
     385        ipc_call_t answer;
    380386       
    381387        IPC_SET_ARG1(answer, 0);
  • uspace/srv/net/udp/ucall.c

    r8fc8969 r451481c8  
    6868{
    6969        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_uc_set_local(%p, %p)", assoc, lsock);
     70       
     71        udp_assoc_set_local(assoc, lsock);
     72        return UDP_EOK;
     73}
    7074
    71         udp_assoc_set_local(assoc, lsock);
     75udp_error_t udp_uc_set_local_port(udp_assoc_t *assoc, uint16_t lport)
     76{
     77        log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_uc_set_local(%p, %" PRIu16 ")", assoc, lport);
     78       
     79        udp_assoc_set_local_port(assoc, lport);
    7280        return UDP_EOK;
    7381}
  • uspace/srv/net/udp/ucall.h

    r8fc8969 r451481c8  
    4242extern udp_error_t udp_uc_set_foreign(udp_assoc_t *, udp_sock_t *);
    4343extern udp_error_t udp_uc_set_local(udp_assoc_t *, udp_sock_t *);
     44extern udp_error_t udp_uc_set_local_port(udp_assoc_t *, uint16_t);
    4445extern udp_error_t udp_uc_send(udp_assoc_t *, udp_sock_t *, void *, size_t,
    4546    xflags_t);
Note: See TracChangeset for help on using the changeset viewer.