Changeset 48171fc4 in mainline


Ignore:
Timestamp:
2013-05-03T08:10:02Z (11 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a0d97f83
Parents:
fff7ef4
Message:

Single fibril for receiving responses. Request timeout.

Location:
uspace/srv/net/dnsrsrv
Files:
4 edited

Legend:

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

    rfff7ef4 r48171fc4  
    4747#include "dns_std.h"
    4848#include "query.h"
     49#include "transport.h"
    4950
    5051#define NAME  "dnsres"
     
    5455static int dnsr_init(void)
    5556{
     57        int rc;
    5658        log_msg(LOG_DEFAULT, LVL_DEBUG, "dnsr_init()");
    5759
     60        rc = transport_init();
     61        if (rc != EOK) {
     62                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing tarnsport.");
     63                return EIO;
     64        }
     65
    5866        async_set_client_connection(dnsr_client_conn);
    5967
    60         int rc = loc_server_register(NAME);
     68        rc = loc_server_register(NAME);
    6169        if (rc != EOK) {
    6270                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server (%d).", rc);
     71                transport_fini();
    6372                return EEXIST;
    6473        }
     
    6877        if (rc != EOK) {
    6978                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
     79                transport_fini();
    7080                return EEXIST;
    7181        }
  • uspace/srv/net/dnsrsrv/query.c

    rfff7ef4 r48171fc4  
    3535
    3636#include <errno.h>
     37#include <io/log.h>
    3738#include <mem.h>
    3839#include <stdlib.h>
     
    4748static uint16_t msg_id;
    4849
    49 #include <stdio.h>
    5050int dns_name2host(const char *name, dns_host_info_t **rinfo)
    5151{
    52         dns_message_t msg;
     52        dns_message_t *msg;
    5353        dns_message_t *amsg;
    5454        dns_question_t question;
     
    6060        question.qclass = DC_IN;
    6161
    62         memset(&msg, 0, sizeof(msg));
     62        msg = calloc(1, sizeof(dns_message_t));
     63        if (msg == NULL)
     64                return ENOMEM;
    6365
    64         list_initialize(&msg.question);
    65         list_append(&question.msg, &msg.question);
     66        list_initialize(&msg->question);
     67        list_append(&question.msg, &msg->question);
    6668
    67         msg.id = msg_id++;
    68         msg.qr = QR_QUERY;
    69         msg.opcode = OPC_QUERY;
    70         msg.aa = false;
    71         msg.tc = false;
    72         msg.rd = true;
    73         msg.ra = false;
     69        msg->id = msg_id++;
     70        msg->qr = QR_QUERY;
     71        msg->opcode = OPC_QUERY;
     72        msg->aa = false;
     73        msg->tc = false;
     74        msg->rd = true;
     75        msg->ra = false;
    7476
    75         rc = dns_request(&msg, &amsg);
    76         if (rc != EOK)
     77        rc = dns_request(msg, &amsg);
     78        if (rc != EOK) {
    7779                return rc;
     80        }
    7881
    7982        list_foreach(amsg->answer, link) {
    8083                dns_rr_t *rr = list_get_instance(link, dns_rr_t, msg);
    8184
    82                 printf(" - '%s' %u/%u, dsize %u\n",
     85                log_msg(LOG_DEFAULT, LVL_DEBUG, " - '%s' %u/%u, dsize %u\n",
    8386                        rr->name, rr->rtype, rr->rclass, rr->rdata_size);
    8487
     
    9497                        info->name = str_dup(rr->name);
    9598                        info->addr.ipv4 = dns_uint32_t_decode(rr->rdata, rr->rdata_size);
    96                         printf("info->addr = %x\n", info->addr.ipv4);
     99                        log_msg(LOG_DEFAULT, LVL_DEBUG, "info->addr = %x\n",
     100                            info->addr.ipv4);
    97101
    98102                        dns_message_destroy(amsg);
     
    102106        }
    103107
     108        dns_message_destroy(msg);
    104109        dns_message_destroy(amsg);
    105         printf("no A/IN found, fail\n");
     110        log_msg(LOG_DEFAULT, LVL_DEBUG, "No A/IN found, fail\n");
    106111
    107112        return EIO;
  • uspace/srv/net/dnsrsrv/transport.c

    rfff7ef4 r48171fc4  
    3434 */
    3535
     36#include <adt/list.h>
    3637#include <errno.h>
     38#include <fibril_synch.h>
     39#include <io/log.h>
    3740#include <net/in.h>
    3841#include <net/inet.h>
    3942#include <net/socket.h>
     43#include <stdbool.h>
    4044#include <stdlib.h>
    4145
     
    4448#include "transport.h"
    4549
    46 #include <stdio.h>
    47 
    4850#define RECV_BUF_SIZE 4096
    4951
     52/** Request timeout (microseconds) */
     53#define REQ_TIMEOUT (5*1000*1000)
     54
     55typedef struct {
     56        link_t lreq;
     57        dns_message_t *req;
     58        dns_message_t *resp;
     59
     60        bool done;
     61        fibril_condvar_t done_cv;
     62        fibril_mutex_t done_lock;
     63
     64        int status;
     65} trans_req_t;
     66
    5067static uint8_t recv_buf[RECV_BUF_SIZE];
     68static fid_t recv_fid;
     69static int transport_fd = -1;
     70
     71/** Outstanding requests */
     72static LIST_INITIALIZE(treq_list);
     73static FIBRIL_MUTEX_INITIALIZE(treq_lock);
     74
     75static int transport_recv_fibril(void *arg);
     76
     77int transport_init(void)
     78{
     79        struct sockaddr_in laddr;
     80        int fd;
     81        fid_t fid;
     82        int rc;
     83
     84        laddr.sin_family = AF_INET;
     85        laddr.sin_port = htons(12345);
     86        laddr.sin_addr.s_addr = INADDR_ANY;
     87
     88        fd = -1;
     89
     90        fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     91        if (fd < 0) {
     92                rc = EIO;
     93                goto error;
     94        }
     95
     96        rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
     97        if (rc != EOK)
     98                goto error;
     99
     100        transport_fd = fd;
     101
     102        fid = fibril_create(transport_recv_fibril, NULL);
     103        if (fid == 0)
     104                goto error;
     105
     106        fibril_add_ready(fid);
     107        recv_fid = fid;
     108        return EOK;
     109error:
     110        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing network socket.\n");
     111        if (fd >= 0)
     112                closesocket(fd);
     113        return rc;
     114}
     115
     116void transport_fini(void)
     117{
     118        if (transport_fd >= 0)
     119                closesocket(transport_fd);
     120}
     121
     122static trans_req_t *treq_create(dns_message_t *req)
     123{
     124        trans_req_t *treq;
     125
     126        treq = calloc(1, sizeof(trans_req_t));
     127        if (treq == NULL)
     128                return NULL;
     129
     130        treq->req = req;
     131        treq->resp = NULL;
     132        treq->done = false;
     133        fibril_condvar_initialize(&treq->done_cv);
     134        fibril_mutex_initialize(&treq->done_lock);
     135
     136        fibril_mutex_lock(&treq_lock);
     137        list_append(&treq->lreq, &treq_list);
     138        fibril_mutex_unlock(&treq_lock);
     139
     140        return treq;
     141}
     142
     143static void treq_destroy(trans_req_t *treq)
     144{
     145        if (link_in_use(&treq->lreq))
     146                list_remove(&treq->lreq);
     147        free(treq);
     148}
     149
     150static trans_req_t *treq_match_resp(dns_message_t *resp)
     151{
     152        assert(fibril_mutex_is_locked(&treq_lock));
     153
     154        list_foreach(treq_list, link) {
     155                trans_req_t *treq = list_get_instance(link, trans_req_t, lreq);
     156
     157                if (treq->req->id == resp->id) {
     158                        /* Match */
     159                        return treq;
     160                }
     161        }
     162
     163        return NULL;
     164}
     165
     166static void treq_complete(trans_req_t *treq, dns_message_t *resp)
     167{
     168        fibril_mutex_lock(&treq->done_lock);
     169        treq->done = true;
     170        treq->status = EOK;
     171        treq->resp = resp;
     172        fibril_mutex_unlock(&treq->done_lock);
     173
     174        fibril_condvar_broadcast(&treq->done_cv);
     175}
    51176
    52177int dns_request(dns_message_t *req, dns_message_t **rresp)
    53178{
    54         dns_message_t *resp;
    55179        int rc;
    56180        void *req_data;
    57181        size_t req_size;
    58182        struct sockaddr_in addr;
    59         struct sockaddr_in laddr;
     183        trans_req_t *treq;
     184
     185        req_data = NULL;
     186        treq = NULL;
     187
     188        addr.sin_family = AF_INET;
     189        addr.sin_port = htons(53);
     190        addr.sin_addr.s_addr = htonl((10 << 24) | (0 << 16) | (0 << 8) | 138);
     191
     192        rc = dns_message_encode(req, &req_data, &req_size);
     193        if (rc != EOK)
     194                goto error;
     195
     196        rc = sendto(transport_fd, req_data, req_size, 0,
     197            (struct sockaddr *)&addr, sizeof(addr));
     198        if (rc != EOK)
     199                goto error;
     200
     201        treq = treq_create(req);
     202        if (treq == NULL) {
     203                rc = ENOMEM;
     204                goto error;
     205        }
     206
     207        fibril_mutex_lock(&treq->done_lock);
     208        while (treq->done != true) {
     209                rc = fibril_condvar_wait_timeout(&treq->done_cv, &treq->done_lock,
     210                    REQ_TIMEOUT);
     211                if (rc == ETIMEOUT) {
     212                        fibril_mutex_unlock(&treq->done_lock);
     213                        rc = EIO;
     214                        goto error;
     215                }
     216        }
     217
     218        fibril_mutex_unlock(&treq->done_lock);
     219
     220        if (treq->status != EOK) {
     221                rc = treq->status;
     222                goto error;
     223        }
     224
     225        *rresp = treq->resp;
     226        treq_destroy(treq);
     227        free(req_data);
     228        return EOK;
     229error:
     230        if (treq != NULL)
     231                treq_destroy(treq);
     232        free(req_data);
     233        return rc;
     234}
     235
     236static int transport_recv_msg(dns_message_t **rresp)
     237{
    60238        struct sockaddr_in src_addr;
    61239        socklen_t src_addr_size;
    62240        size_t recv_size;
    63         int fd;
    64         int i;
    65 
    66         addr.sin_family = AF_INET;
    67         addr.sin_port = htons(53);
    68         addr.sin_addr.s_addr = htonl((10 << 24) | (0 << 16) | (0 << 8) | 138);
    69 
    70         laddr.sin_family = AF_INET;
    71         laddr.sin_port = htons(12345);
    72         laddr.sin_addr.s_addr = INADDR_ANY;
    73 
    74         req_data = NULL;
    75         fd = -1;
    76 
    77         rc = dns_message_encode(req, &req_data, &req_size);
    78         if (rc != EOK)
    79                 goto error;
    80 
    81         fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    82         if (fd < 0) {
    83                 rc = EIO;
    84                 goto error;
    85         }
    86 
    87         rc = bind(fd, (struct sockaddr *)&laddr, sizeof(laddr));
    88         if (rc != EOK)
    89                 goto error;
    90 
    91         printf("fd=%d req_data=%p, req_size=%zu\n", fd, req_data, req_size);
    92         rc = sendto(fd, req_data, req_size, 0, (struct sockaddr *)&addr,
    93             sizeof(addr));
    94         if (rc != EOK)
    95                 goto error;
     241        dns_message_t *resp;
     242        int rc;
    96243
    97244        src_addr_size = sizeof(src_addr);
    98         rc = recvfrom(fd, recv_buf, RECV_BUF_SIZE, 0,
     245        rc = recvfrom(transport_fd, recv_buf, RECV_BUF_SIZE, 0,
    99246            (struct sockaddr *)&src_addr, &src_addr_size);
    100247        if (rc < 0) {
    101                 printf("recvfrom returns error - %d\n", rc);
     248                log_msg(LOG_DEFAULT, LVL_ERROR, "recvfrom returns error - %d\n", rc);
    102249                goto error;
    103250        }
    104251
    105252        recv_size = (size_t)rc;
    106 
    107         printf("received %d bytes\n", (int)recv_size);
    108         for (i = 0; i < (int)recv_size; i++) {
    109                 if (recv_buf[i] >= 32 && recv_buf[i] < 127)
    110                         printf("%c", recv_buf[i]);
    111                 else
    112                         printf("?");
    113         }
    114         printf("\n");
    115 
    116         printf("close socket\n");
    117         closesocket(fd);
    118         printf("free req_data\n");
    119         free(req_data);
    120253
    121254        rc = dns_message_decode(recv_buf, recv_size, &resp);
     
    129262
    130263error:
    131         if (req_data != NULL)
    132                 free(req_data);
    133         if (fd >= 0)
    134                 closesocket(fd);
    135264        return rc;
    136265}
    137266
     267static int transport_recv_fibril(void *arg)
     268{
     269        dns_message_t *resp;
     270        trans_req_t *treq;
     271        int rc;
     272
     273        while (true) {
     274                rc = transport_recv_msg(&resp);
     275                if (rc != EOK)
     276                        continue;
     277
     278                fibril_mutex_lock(&treq_lock);
     279                treq = treq_match_resp(resp);
     280                if (treq == NULL) {
     281                        fibril_mutex_unlock(&treq_lock);
     282                        continue;
     283                }
     284
     285                list_remove(&treq->lreq);
     286                fibril_mutex_unlock(&treq_lock);
     287
     288                treq_complete(treq, resp);
     289        }
     290
     291        return 0;
     292}
     293
    138294/** @}
    139295 */
  • uspace/srv/net/dnsrsrv/transport.h

    rfff7ef4 r48171fc4  
    3939#include "dns_type.h"
    4040
     41extern int transport_init(void);
     42extern void transport_fini(void);
    4143extern int dns_request(dns_message_t *, dns_message_t **);
    4244
Note: See TracChangeset for help on using the changeset viewer.