Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/dnsrsrv/transport.c

    rfab2746 rb5f716b  
    3737#include <errno.h>
    3838#include <fibril_synch.h>
    39 #include <inet/addr.h>
    40 #include <inet/endpoint.h>
    41 #include <inet/udp.h>
    4239#include <io/log.h>
     40#include <net/in.h>
     41#include <net/inet.h>
     42#include <net/socket.h>
    4343#include <stdbool.h>
    4444#include <stdlib.h>
     
    7272
    7373static uint8_t recv_buf[RECV_BUF_SIZE];
    74 static udp_t *transport_udp;
    75 static udp_assoc_t *transport_assoc;
     74static fid_t recv_fid;
     75static int transport_fd = -1;
    7676
    7777/** Outstanding requests */
     
    7979static FIBRIL_MUTEX_INITIALIZE(treq_lock);
    8080
    81 static void transport_recv_msg(udp_assoc_t *, udp_rmsg_t *);
    82 static void transport_recv_err(udp_assoc_t *, udp_rerr_t *);
    83 static void transport_link_state(udp_assoc_t *, udp_link_state_t);
    84 
    85 static udp_cb_t transport_cb = {
    86         .recv_msg = transport_recv_msg,
    87         .recv_err = transport_recv_err,
    88         .link_state = transport_link_state
    89 };
     81static int transport_recv_fibril(void *arg);
    9082
    9183int transport_init(void)
    9284{
    93         inet_ep2_t epp;
     85        struct sockaddr_in laddr;
     86        int fd;
     87        fid_t fid;
    9488        int rc;
    9589
    96         inet_ep2_init(&epp);
    97 
    98         rc = udp_create(&transport_udp);
    99         if (rc != EOK) {
     90        laddr.sin_family = AF_INET;
     91        laddr.sin_port = htons(12345);
     92        laddr.sin_addr.s_addr = INADDR_ANY;
     93
     94        fd = -1;
     95
     96        fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     97        if (fd < 0) {
    10098                rc = EIO;
    10199                goto error;
    102100        }
    103101
    104         rc = udp_assoc_create(transport_udp, &epp, &transport_cb, NULL,
    105             &transport_assoc);
    106         if (rc != EOK) {
    107                 rc = EIO;
    108                 goto error;
    109         }
    110 
     102        rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
     103        if (rc != EOK)
     104                goto error;
     105
     106        transport_fd = fd;
     107
     108        fid = fibril_create(transport_recv_fibril, NULL);
     109        if (fid == 0)
     110                goto error;
     111
     112        fibril_add_ready(fid);
     113        recv_fid = fid;
    111114        return EOK;
    112115error:
    113         log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network.");
    114         udp_assoc_destroy(transport_assoc);
    115         udp_destroy(transport_udp);
     116        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network socket.");
     117        if (fd >= 0)
     118                closesocket(fd);
    116119        return rc;
    117120}
     
    119122void transport_fini(void)
    120123{
    121         udp_assoc_destroy(transport_assoc);
    122         udp_destroy(transport_udp);
     124        if (transport_fd >= 0)
     125                closesocket(transport_fd);
    123126}
    124127
     
    179182{
    180183        trans_req_t *treq = NULL;
    181         inet_ep_t ep;
    182 
     184        struct sockaddr *saddr = NULL;
     185        socklen_t saddrlen;
     186       
    183187        void *req_data;
    184188        size_t req_size;
     
    186190        if (rc != EOK)
    187191                goto error;
    188 
    189         inet_ep_init(&ep);
    190         ep.addr = dns_server_addr;
    191         ep.port = DNS_SERVER_PORT;
    192 
     192       
     193        rc = inet_addr_sockaddr(&dns_server_addr, DNS_SERVER_PORT,
     194            &saddr, &saddrlen);
     195        if (rc != EOK) {
     196                assert(rc == ENOMEM);
     197                goto error;
     198        }
     199       
    193200        size_t ntry = 0;
    194 
     201       
    195202        while (ntry < REQ_RETRY_MAX) {
    196                 rc = udp_assoc_send_msg(transport_assoc, &ep, req_data,
    197                     req_size);
     203                rc = sendto(transport_fd, req_data, req_size, 0,
     204                    saddr, saddrlen);
    198205                if (rc != EOK)
    199206                        goto error;
    200 
     207               
    201208                treq = treq_create(req);
    202209                if (treq == NULL) {
     
    204211                        goto error;
    205212                }
    206 
     213               
    207214                fibril_mutex_lock(&treq->done_lock);
    208215                while (treq->done != true) {
     
    214221                        }
    215222                }
    216 
     223               
    217224                fibril_mutex_unlock(&treq->done_lock);
    218 
     225               
    219226                if (rc != ETIMEOUT)
    220227                        break;
    221228        }
    222 
     229       
    223230        if (ntry >= REQ_RETRY_MAX) {
    224231                rc = EIO;
    225232                goto error;
    226233        }
    227 
     234       
    228235        if (treq->status != EOK) {
    229236                rc = treq->status;
    230237                goto error;
    231238        }
    232 
     239       
    233240        *rresp = treq->resp;
    234241        treq_destroy(treq);
    235242        free(req_data);
     243        free(saddr);
    236244        return EOK;
    237 
     245       
    238246error:
    239247        if (treq != NULL)
    240248                treq_destroy(treq);
    241 
     249       
    242250        free(req_data);
     251        free(saddr);
    243252        return rc;
    244253}
    245254
    246 static void transport_recv_msg(udp_assoc_t *assoc, udp_rmsg_t *rmsg)
     255static int transport_recv_msg(dns_message_t **rresp)
     256{
     257        struct sockaddr_in src_addr;
     258        socklen_t src_addr_size;
     259        size_t recv_size;
     260        dns_message_t *resp;
     261        int rc;
     262
     263        src_addr_size = sizeof(src_addr);
     264        rc = recvfrom(transport_fd, recv_buf, RECV_BUF_SIZE, 0,
     265            (struct sockaddr *)&src_addr, &src_addr_size);
     266        if (rc < 0) {
     267                log_msg(LOG_DEFAULT, LVL_ERROR, "recvfrom returns error - %d", rc);
     268                goto error;
     269        }
     270
     271        recv_size = (size_t)rc;
     272
     273        rc = dns_message_decode(recv_buf, recv_size, &resp);
     274        if (rc != EOK) {
     275                rc = EIO;
     276                goto error;
     277        }
     278
     279        *rresp = resp;
     280        return EOK;
     281
     282error:
     283        return rc;
     284}
     285
     286static int transport_recv_fibril(void *arg)
    247287{
    248288        dns_message_t *resp = NULL;
    249289        trans_req_t *treq;
    250         size_t size;
    251         inet_ep_t remote_ep;
    252290        int rc;
    253291
    254         size = udp_rmsg_size(rmsg);
    255         if (size > RECV_BUF_SIZE)
    256                 size = RECV_BUF_SIZE; /* XXX */
    257 
    258         rc = udp_rmsg_read(rmsg, 0, recv_buf, size);
    259         if (rc != EOK) {
    260                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error reading message.");
    261                 return;
    262         }
    263 
    264         udp_rmsg_remote_ep(rmsg, &remote_ep);
    265         /* XXX */
    266 
    267         rc = dns_message_decode(recv_buf, size, &resp);
    268         if (rc != EOK) {
    269                 log_msg(LOG_DEFAULT, LVL_ERROR, "Error decoding message.");
    270                 return;
    271         }
    272 
    273         assert(resp != NULL);
    274 
    275         fibril_mutex_lock(&treq_lock);
    276         treq = treq_match_resp(resp);
    277         if (treq == NULL) {
     292        while (true) {
     293                rc = transport_recv_msg(&resp);
     294                if (rc != EOK)
     295                        continue;
     296
     297                assert(resp != NULL);
     298
     299                fibril_mutex_lock(&treq_lock);
     300                treq = treq_match_resp(resp);
     301                if (treq == NULL) {
     302                        fibril_mutex_unlock(&treq_lock);
     303                        continue;
     304                }
     305
     306                list_remove(&treq->lreq);
    278307                fibril_mutex_unlock(&treq_lock);
    279                 return;
    280         }
    281 
    282         list_remove(&treq->lreq);
    283         fibril_mutex_unlock(&treq_lock);
    284 
    285         treq_complete(treq, resp);
    286 }
    287 
    288 static void transport_recv_err(udp_assoc_t *assoc, udp_rerr_t *rerr)
    289 {
    290         log_msg(LOG_DEFAULT, LVL_WARN, "Ignoring ICMP error");
    291 }
    292 
    293 static void transport_link_state(udp_assoc_t *assoc, udp_link_state_t ls)
    294 {
    295         log_msg(LOG_DEFAULT, LVL_NOTE, "Link state change");
    296 }
    297 
     308
     309                treq_complete(treq, resp);
     310        }
     311
     312        return 0;
     313}
    298314
    299315/** @}
Note: See TracChangeset for help on using the changeset viewer.