Changeset 02a09ed in mainline for uspace/srv/net/tcp/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/tcp/sock.c

    redf0d27 r02a09ed  
    354354}
    355355
    356 static void tcp_sock_connect(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    357 {
    358         int rc;
    359         struct sockaddr_in *addr;
    360         int socket_id;
     356static void tcp_sock_connect(tcp_client_t *client, ipc_callid_t callid,
     357    ipc_call_t call)
     358{
     359        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect()");
     360       
     361        struct sockaddr_in6 *addr6 = NULL;
    361362        size_t addr_len;
    362         socket_core_t *sock_core;
    363         tcp_sockdata_t *socket;
    364         tcp_error_t trc;
    365         tcp_sock_t lsocket;
    366         tcp_sock_t fsocket;
    367 
    368         log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect()");
    369 
    370         rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len);
    371         if (rc != EOK || addr_len != sizeof(struct sockaddr_in)) {
     363        int rc = async_data_write_accept((void **) &addr6, false, 0, 0, 0, &addr_len);
     364        if (rc != EOK) {
    372365                async_answer_0(callid, rc);
    373366                return;
    374367        }
    375 
    376         socket_id = SOCKET_GET_SOCKET_ID(call);
    377 
    378         sock_core = socket_cores_find(&client->sockets, socket_id);
     368       
     369        if ((addr_len != sizeof(struct sockaddr_in)) &&
     370            (addr_len != sizeof(struct sockaddr_in6))) {
     371                async_answer_0(callid, EINVAL);
     372                goto out;
     373        }
     374       
     375        struct sockaddr_in *addr = (struct sockaddr_in *) addr6;
     376       
     377        int socket_id = SOCKET_GET_SOCKET_ID(call);
     378        socket_core_t *sock_core = socket_cores_find(&client->sockets,
     379            socket_id);
    379380        if (sock_core == NULL) {
    380381                async_answer_0(callid, ENOTSOCK);
    381                 return;
    382         }
    383 
    384         socket = (tcp_sockdata_t *)sock_core->specific_data;
     382                goto out;
     383        }
     384       
     385        tcp_sockdata_t *socket =
     386            (tcp_sockdata_t *) sock_core->specific_data;
     387       
    385388        if (sock_core->port <= 0) {
    386389                rc = socket_bind_free_port(&gsock, sock_core,
     
    389392                if (rc != EOK) {
    390393                        async_answer_0(callid, rc);
    391                         return;
     394                        goto out;
    392395                }
    393396               
    394397                last_used_port = sock_core->port;
    395398        }
    396 
     399       
    397400        fibril_mutex_lock(&socket->lock);
    398 
     401       
    399402        if (inet_addr_is_any(&socket->laddr)) {
    400403                /* Determine local IP address */
     
    402405                inet_addr_t rem_addr;
    403406               
    404                 inet_addr_unpack(uint32_t_be2host(addr->sin_addr.s_addr),
    405                     &rem_addr);
     407                switch (addr->sin_family) {
     408                case AF_INET:
     409                        inet_sockaddr_in_addr(addr, &rem_addr);
     410                        break;
     411                case AF_INET6:
     412                        inet_sockaddr_in6_addr(addr6, &rem_addr);
     413                        break;
     414                default:
     415                        fibril_mutex_unlock(&socket->lock);
     416                        async_answer_0(callid, EINVAL);
     417                        goto out;
     418                }
     419               
    406420                rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
    407421                if (rc != EOK) {
     
    410424                        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect: Failed to "
    411425                            "determine local address.");
    412                         return;
     426                        goto out;
    413427                }
    414428               
     
    416430        }
    417431       
     432        tcp_sock_t lsocket;
     433        tcp_sock_t fsocket;
     434       
    418435        lsocket.addr = socket->laddr;
    419436        lsocket.port = sock_core->port;
    420437       
    421         inet_addr_unpack(uint32_t_be2host(addr->sin_addr.s_addr),
    422             &fsocket.addr);
     438        switch (addr->sin_family) {
     439        case AF_INET:
     440                inet_sockaddr_in_addr(addr, &fsocket.addr);
     441                break;
     442        case AF_INET6:
     443                inet_sockaddr_in6_addr(addr6, &fsocket.addr);
     444                break;
     445        default:
     446                fibril_mutex_unlock(&socket->lock);
     447                async_answer_0(callid, EINVAL);
     448                goto out;
     449        }
     450       
    423451        fsocket.port = uint16_t_be2host(addr->sin_port);
    424 
    425         trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0, &socket->conn);
    426 
     452       
     453        tcp_error_t trc = tcp_uc_open(&lsocket, &fsocket, ap_active, 0,
     454            &socket->conn);
     455       
    427456        if (socket->conn != NULL)
    428                 socket->conn->name = (char *)"C";
    429 
     457                socket->conn->name = (char *) "C";
     458       
    430459        fibril_mutex_unlock(&socket->lock);
    431460       
     
    445474       
    446475        async_answer_0(callid, rc);
     476       
     477out:
     478        if (addr6 != NULL)
     479                free(addr6);
    447480}
    448481
     
    662695static void tcp_sock_recvfrom(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
    663696{
    664         int socket_id;
    665         int flags;
    666         size_t addr_length, length;
    667         socket_core_t *sock_core;
    668         tcp_sockdata_t *socket;
    669         ipc_call_t answer;
    670         ipc_callid_t rcallid;
    671         size_t data_len;
    672         struct sockaddr_in addr;
    673         tcp_sock_t *rsock;
    674         int rc;
    675 
    676697        log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: tcp_sock_recv[from]()", client);
    677 
    678         socket_id = SOCKET_GET_SOCKET_ID(call);
    679         flags = SOCKET_GET_FLAGS(call);
    680 
    681         sock_core = socket_cores_find(&client->sockets, socket_id);
     698       
     699        int socket_id = SOCKET_GET_SOCKET_ID(call);
     700       
     701        socket_core_t *sock_core =
     702            socket_cores_find(&client->sockets, socket_id);
    682703        if (sock_core == NULL) {
    683704                async_answer_0(callid, ENOTSOCK);
    684705                return;
    685706        }
    686 
    687         socket = (tcp_sockdata_t *)sock_core->specific_data;
     707       
     708        tcp_sockdata_t *socket =
     709            (tcp_sockdata_t *) sock_core->specific_data;
     710       
    688711        fibril_mutex_lock(&socket->lock);
    689712       
     
    693716                return;
    694717        }
    695 
    696         (void)flags;
    697 
     718       
    698719        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recvfrom(): lock recv_buffer_lock");
     720       
    699721        fibril_mutex_lock(&socket->recv_buffer_lock);
    700         while (socket->recv_buffer_used == 0 && socket->recv_error == TCP_EOK) {
     722        while ((socket->recv_buffer_used == 0) &&
     723            (socket->recv_error == TCP_EOK)) {
    701724                log_msg(LOG_DEFAULT, LVL_DEBUG, "wait for recv_buffer_cv + recv_buffer_used != 0");
    702725                fibril_condvar_wait(&socket->recv_buffer_cv,
     
    705728       
    706729        log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer");
    707 
    708         data_len = socket->recv_buffer_used;
    709         rc = socket->recv_error;
    710 
    711         switch (socket->recv_error) {
     730       
     731        size_t data_len = socket->recv_buffer_used;
     732        tcp_error_t trc = socket->recv_error;
     733        int rc;
     734       
     735        switch (trc) {
    712736        case TCP_EOK:
    713737                rc = EOK;
     
    732756                return;
    733757        }
    734 
     758       
     759        ipc_callid_t rcallid;
     760       
    735761        if (IPC_GET_IMETHOD(call) == NET_SOCKET_RECVFROM) {
    736762                /* Fill address */
    737                 rsock = &socket->conn->ident.foreign;
     763                tcp_sock_t *rsock = &socket->conn->ident.foreign;
     764                struct sockaddr_in addr;
     765                struct sockaddr_in6 addr6;
     766                size_t addr_length;
    738767               
    739                 uint32_t rsock_addr;
    740                 int rc = inet_addr_pack(&rsock->addr, &rsock_addr);
    741                 if (rc != EOK) {
    742                         fibril_mutex_unlock(&socket->recv_buffer_lock);
    743                         fibril_mutex_unlock(&socket->lock);
    744                         async_answer_0(callid, rc);
    745                         return;
    746                 }
     768                uint16_t addr_af = inet_addr_sockaddr_in(&rsock->addr, &addr,
     769                    &addr6);
    747770               
    748                 addr.sin_family = AF_INET;
    749                 addr.sin_addr.s_addr = host2uint32_t_be(rsock_addr);
    750                 addr.sin_port = host2uint16_t_be(rsock->port);
    751 
    752                 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
    753                 if (!async_data_read_receive(&rcallid, &addr_length)) {
     771                switch (addr_af) {
     772                case AF_INET:
     773                        addr.sin_port = host2uint16_t_be(rsock->port);
     774                       
     775                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
     776                        if (!async_data_read_receive(&rcallid, &addr_length)) {
     777                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     778                                fibril_mutex_unlock(&socket->lock);
     779                                async_answer_0(callid, EINVAL);
     780                                return;
     781                        }
     782                       
     783                        if (addr_length > sizeof(addr))
     784                                addr_length = sizeof(addr);
     785                       
     786                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
     787                        rc = async_data_read_finalize(rcallid, &addr, addr_length);
     788                        if (rc != EOK) {
     789                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     790                                fibril_mutex_unlock(&socket->lock);
     791                                async_answer_0(callid, EINVAL);
     792                                return;
     793                        }
     794                       
     795                        break;
     796                case AF_INET6:
     797                        addr6.sin6_port = host2uint16_t_be(rsock->port);
     798                       
     799                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read receive");
     800                        if (!async_data_read_receive(&rcallid, &addr_length)) {
     801                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     802                                fibril_mutex_unlock(&socket->lock);
     803                                async_answer_0(callid, EINVAL);
     804                                return;
     805                        }
     806                       
     807                        if (addr_length > sizeof(addr6))
     808                                addr_length = sizeof(addr6);
     809                       
     810                        log_msg(LOG_DEFAULT, LVL_DEBUG, "addr6 read finalize");
     811                        rc = async_data_read_finalize(rcallid, &addr6, addr_length);
     812                        if (rc != EOK) {
     813                                fibril_mutex_unlock(&socket->recv_buffer_lock);
     814                                fibril_mutex_unlock(&socket->lock);
     815                                async_answer_0(callid, EINVAL);
     816                                return;
     817                        }
     818                       
     819                        break;
     820                default:
    754821                        fibril_mutex_unlock(&socket->recv_buffer_lock);
    755822                        fibril_mutex_unlock(&socket->lock);
     
    757824                        return;
    758825                }
    759 
    760                 if (addr_length > sizeof(addr))
    761                         addr_length = sizeof(addr);
    762 
    763                 log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
    764                 rc = async_data_read_finalize(rcallid, &addr, addr_length);
    765                 if (rc != EOK) {
    766                         fibril_mutex_unlock(&socket->recv_buffer_lock);
    767                         fibril_mutex_unlock(&socket->lock);
    768                         async_answer_0(callid, EINVAL);
    769                         return;
    770                 }
    771826        }
    772827       
    773828        log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive");
     829       
     830        size_t length;
    774831        if (!async_data_read_receive(&rcallid, &length)) {
    775832                fibril_mutex_unlock(&socket->recv_buffer_lock);
     
    783840       
    784841        log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize");
     842       
    785843        rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
    786844       
    787845        socket->recv_buffer_used -= length;
     846       
    788847        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recvfrom: %zu left in buffer",
    789848            socket->recv_buffer_used);
     849       
    790850        if (socket->recv_buffer_used > 0) {
    791851                memmove(socket->recv_buffer, socket->recv_buffer + length,
     
    795855       
    796856        fibril_condvar_broadcast(&socket->recv_buffer_cv);
    797 
    798         if (length < data_len && rc == EOK)
     857       
     858        if ((length < data_len) && (rc == EOK))
    799859                rc = EOVERFLOW;
    800 
     860       
     861        ipc_call_t answer;
     862       
    801863        SOCKET_SET_READ_DATA_LENGTH(answer, length);
    802864        async_answer_1(callid, EOK, IPC_GET_ARG1(answer));
Note: See TracChangeset for help on using the changeset viewer.