Ignore:
File:
1 edited

Legend:

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

    r02a09ed rfab2746  
    3737#include <errno.h>
    3838#include <fibril_synch.h>
     39#include <inet/addr.h>
     40#include <inet/endpoint.h>
     41#include <inet/udp.h>
    3942#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 fid_t recv_fid;
    75 static int transport_fd = -1;
     74static udp_t *transport_udp;
     75static udp_assoc_t *transport_assoc;
    7676
    7777/** Outstanding requests */
     
    7979static FIBRIL_MUTEX_INITIALIZE(treq_lock);
    8080
    81 static int transport_recv_fibril(void *arg);
     81static void transport_recv_msg(udp_assoc_t *, udp_rmsg_t *);
     82static void transport_recv_err(udp_assoc_t *, udp_rerr_t *);
     83static void transport_link_state(udp_assoc_t *, udp_link_state_t);
     84
     85static udp_cb_t transport_cb = {
     86        .recv_msg = transport_recv_msg,
     87        .recv_err = transport_recv_err,
     88        .link_state = transport_link_state
     89};
    8290
    8391int transport_init(void)
    8492{
    85         struct sockaddr_in laddr;
    86         int fd;
    87         fid_t fid;
     93        inet_ep2_t epp;
    8894        int rc;
    8995
    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) {
     96        inet_ep2_init(&epp);
     97
     98        rc = udp_create(&transport_udp);
     99        if (rc != EOK) {
    98100                rc = EIO;
    99101                goto error;
    100102        }
    101103
    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;
     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
    114111        return EOK;
    115112error:
    116         log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network socket.");
    117         if (fd >= 0)
    118                 closesocket(fd);
     113        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network.");
     114        udp_assoc_destroy(transport_assoc);
     115        udp_destroy(transport_udp);
    119116        return rc;
    120117}
     
    122119void transport_fini(void)
    123120{
    124         if (transport_fd >= 0)
    125                 closesocket(transport_fd);
     121        udp_assoc_destroy(transport_assoc);
     122        udp_destroy(transport_udp);
    126123}
    127124
     
    158155        assert(fibril_mutex_is_locked(&treq_lock));
    159156
    160         list_foreach(treq_list, link) {
    161                 trans_req_t *treq = list_get_instance(link, trans_req_t, lreq);
    162 
     157        list_foreach(treq_list, lreq, trans_req_t, treq) {
    163158                if (treq->req->id == resp->id) {
    164159                        /* Match */
     
    184179{
    185180        trans_req_t *treq = NULL;
    186        
     181        inet_ep_t ep;
     182
    187183        void *req_data;
    188184        size_t req_size;
     
    190186        if (rc != EOK)
    191187                goto error;
    192        
    193         struct sockaddr_in addr;
    194         struct sockaddr_in6 addr6;
    195         uint16_t af =
    196             inet_addr_sockaddr_in(&dns_server_addr, &addr, &addr6);
    197        
    198         struct sockaddr *address;
    199         socklen_t addrlen;
    200        
    201         switch (af) {
    202         case AF_INET:
    203                 addr.sin_port = htons(DNS_SERVER_PORT);
    204                 address = (struct sockaddr *) &addr;
    205                 addrlen = sizeof(addr);
    206                 break;
    207         case AF_INET6:
    208                 addr6.sin6_port = htons(DNS_SERVER_PORT);
    209                 address = (struct sockaddr *) &addr6;
    210                 addrlen = sizeof(addr6);
    211                 break;
    212         default:
    213                 rc = EAFNOSUPPORT;
    214                 goto error;
    215         }
    216        
     188
     189        inet_ep_init(&ep);
     190        ep.addr = dns_server_addr;
     191        ep.port = DNS_SERVER_PORT;
     192
    217193        size_t ntry = 0;
    218        
     194
    219195        while (ntry < REQ_RETRY_MAX) {
    220                 rc = sendto(transport_fd, req_data, req_size, 0,
    221                     (struct sockaddr *) address, addrlen);
     196                rc = udp_assoc_send_msg(transport_assoc, &ep, req_data,
     197                    req_size);
    222198                if (rc != EOK)
    223199                        goto error;
    224                
     200
    225201                treq = treq_create(req);
    226202                if (treq == NULL) {
     
    228204                        goto error;
    229205                }
    230                
     206
    231207                fibril_mutex_lock(&treq->done_lock);
    232208                while (treq->done != true) {
     
    238214                        }
    239215                }
    240                
     216
    241217                fibril_mutex_unlock(&treq->done_lock);
    242                
     218
    243219                if (rc != ETIMEOUT)
    244220                        break;
    245221        }
    246        
     222
    247223        if (ntry >= REQ_RETRY_MAX) {
    248224                rc = EIO;
    249225                goto error;
    250226        }
    251        
     227
    252228        if (treq->status != EOK) {
    253229                rc = treq->status;
    254230                goto error;
    255231        }
    256        
     232
    257233        *rresp = treq->resp;
    258234        treq_destroy(treq);
    259235        free(req_data);
    260236        return EOK;
    261        
     237
    262238error:
    263239        if (treq != NULL)
    264240                treq_destroy(treq);
    265        
     241
    266242        free(req_data);
    267243        return rc;
    268244}
    269245
    270 static int transport_recv_msg(dns_message_t **rresp)
    271 {
    272         struct sockaddr_in src_addr;
    273         socklen_t src_addr_size;
    274         size_t recv_size;
    275         dns_message_t *resp;
     246static void transport_recv_msg(udp_assoc_t *assoc, udp_rmsg_t *rmsg)
     247{
     248        dns_message_t *resp = NULL;
     249        trans_req_t *treq;
     250        size_t size;
     251        inet_ep_t remote_ep;
    276252        int rc;
    277253
    278         src_addr_size = sizeof(src_addr);
    279         rc = recvfrom(transport_fd, recv_buf, RECV_BUF_SIZE, 0,
    280             (struct sockaddr *)&src_addr, &src_addr_size);
    281         if (rc < 0) {
    282                 log_msg(LOG_DEFAULT, LVL_ERROR, "recvfrom returns error - %d", rc);
    283                 goto error;
    284         }
    285 
    286         recv_size = (size_t)rc;
    287 
    288         rc = dns_message_decode(recv_buf, recv_size, &resp);
     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);
    289259        if (rc != EOK) {
    290                 rc = EIO;
    291                 goto error;
    292         }
    293 
    294         *rresp = resp;
    295         return EOK;
    296 
    297 error:
    298         return rc;
    299 }
    300 
    301 static int transport_recv_fibril(void *arg)
    302 {
    303         dns_message_t *resp;
    304         trans_req_t *treq;
    305         int rc;
    306 
    307         while (true) {
    308                 rc = transport_recv_msg(&resp);
    309                 if (rc != EOK)
    310                         continue;
    311 
    312                 fibril_mutex_lock(&treq_lock);
    313                 treq = treq_match_resp(resp);
    314                 if (treq == NULL) {
    315                         fibril_mutex_unlock(&treq_lock);
    316                         continue;
    317                 }
    318 
    319                 list_remove(&treq->lreq);
     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) {
    320278                fibril_mutex_unlock(&treq_lock);
    321 
    322                 treq_complete(treq, resp);
    323         }
    324 
    325         return 0;
    326 }
     279                return;
     280        }
     281
     282        list_remove(&treq->lreq);
     283        fibril_mutex_unlock(&treq_lock);
     284
     285        treq_complete(treq, resp);
     286}
     287
     288static 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
     293static 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
    327298
    328299/** @}
Note: See TracChangeset for help on using the changeset viewer.