Changes in / [acdb5bac:6e8ed225] in mainline


Ignore:
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/include/arch/pm.h

    racdb5bac r6e8ed225  
    5757#ifdef CONFIG_FB
    5858
    59 #define VESA_INIT_DES      8
    6059#define VESA_INIT_SEGMENT  0x8000
     60#define VESA_INIT_CODE_DES      8
     61#define VESA_INIT_DATA_DES      9
    6162
    6263#undef GDT_ITEMS
    63 #define GDT_ITEMS  9
     64#define GDT_ITEMS  10
    6465
    6566#endif /* CONFIG_FB */
  • kernel/arch/amd64/src/pm.c

    racdb5bac r6e8ed225  
    112112        /* VESA Init descriptor */
    113113#ifdef CONFIG_FB
    114         {
    115                 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | DPL_KERNEL,
    116                     0xf, 0, 0, 0, 0, 0
    117         }
     114        { 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | AR_READABLE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 },
     115        { 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
    118116#endif
    119117};
  • kernel/arch/ia32/include/arch/pm.h

    racdb5bac r6e8ed225  
    5050
    5151#define VESA_INIT_SEGMENT  0x8000
    52 #define VESA_INIT_DES      7
     52#define VESA_INIT_CODE_DES      7
     53#define VESA_INIT_DATA_DES      8
    5354#define KTEXT32_DES        KTEXT_DES
    5455
    5556#undef GDT_ITEMS
    56 #define GDT_ITEMS  8
     57#define GDT_ITEMS  9
    5758
    5859#endif /* CONFIG_FB */
     
    6768#define AR_CODE       (3 << 3)
    6869#define AR_WRITABLE   (1 << 1)
     70#define AR_READABLE   (1 << 1)
    6971#define AR_INTERRUPT  (0xe)
    7072#define AR_TRAP       (0xf)
  • kernel/arch/ia32/src/boot/vesa_real.inc

    racdb5bac r6e8ed225  
    3131vesa_init:
    3232        lidtl vesa_idtr
    33         jmp $GDT_SELECTOR(VESA_INIT_DES), $vesa_init_real - vesa_init
     33       
     34        mov $GDT_SELECTOR(VESA_INIT_DATA_DES), %bx
     35       
     36        mov %bx, %es
     37        mov %bx, %fs
     38        mov %bx, %gs
     39        mov %bx, %ds
     40        mov %bx, %ss
     41       
     42        jmp $GDT_SELECTOR(VESA_INIT_CODE_DES), $vesa_init_real - vesa_init
    3443
    3544vesa_idtr:
     
    3948.code16
    4049vesa_init_real:
    41        
    4250        mov %cr0, %eax
    4351        and $~1, %eax
     
    4553       
    4654        jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
    47        
     55
    4856vesa_init_real2:
    4957        mov $VESA_INIT_SEGMENT, %bx
  • kernel/arch/ia32/src/pm.c

    racdb5bac r6e8ed225  
    7575        /* VESA Init descriptor */
    7676#ifdef CONFIG_FB
    77         { 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
     77        { 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | AR_READABLE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 },
     78        { 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
    7879#endif
    7980};
  • uspace/app/dnsres/dnsres.c

    racdb5bac r6e8ed225  
    5050        int rc;
    5151        dnsr_hostinfo_t *hinfo;
     52        char *hname;
    5253        char *saddr;
    5354
     
    5758        }
    5859
    59         rc = dnsr_name2host(argv[1], &hinfo);
     60        hname = argv[1];
     61
     62        rc = dnsr_name2host(hname, &hinfo);
    6063        if (rc != EOK) {
    6164                printf(NAME ": Error resolving '%s'.\n", argv[1]);
     
    7073        }
    7174
    72         printf("Host name: %s address: %s\n", hinfo->name, saddr);
     75        printf("Host name: %s\n", hname);
     76        if (str_cmp(hname, hinfo->cname) != 0)
     77                printf("Canonical name: %s\n", hinfo->cname);
     78        printf("Address: %s\n", saddr);
     79
    7380        dnsr_hostinfo_destroy(hinfo);
    7481        free(saddr);
  • uspace/app/ping/ping.c

    racdb5bac r6e8ed225  
    234234
    235235        if (hinfo != NULL) {
    236                 rc = asprintf(&sdest, "%s (%s)", hinfo->name, adest);
     236                rc = asprintf(&sdest, "%s (%s)", hinfo->cname, adest);
    237237                if (rc < 0) {
    238238                        printf(NAME ": Out of memory.\n");
  • uspace/lib/c/generic/dnsr.c

    racdb5bac r6e8ed225  
    7171{
    7272        async_exch_t *exch = dnsr_exchange_begin();
     73        char cname_buf[DNSR_NAME_MAX_SIZE + 1];
     74        ipc_call_t cnreply;
     75        size_t act_size;
    7376        dnsr_hostinfo_t *info;
    7477
     
    7679        aid_t req = async_send_0(exch, DNSR_NAME2HOST, &answer);
    7780        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     81        aid_t cnreq = async_data_read(exch, cname_buf, DNSR_NAME_MAX_SIZE,
     82            &cnreply);
    7883
    7984        dnsr_exchange_end(exch);
     
    8186        if (retval != EOK) {
    8287                async_forget(req);
     88                async_forget(cnreq);
    8389                return retval;
    8490        }
    8591
    8692        async_wait_for(req, &retval);
     93        if (retval != EOK) {
     94                async_forget(cnreq);
     95                return EIO;
     96        }
     97
     98        async_wait_for(cnreq, &retval);
    8799        if (retval != EOK)
    88100                return EIO;
     
    92104                return ENOMEM;
    93105
    94         info->name = str_dup(name);
     106        act_size = IPC_GET_ARG2(cnreply);
     107        assert(act_size <= DNSR_NAME_MAX_SIZE);
     108        cname_buf[act_size] = '\0';
     109
     110        info->cname = str_dup(cname_buf);
    95111        info->addr.ipv4 = IPC_GET_ARG1(answer);
    96112
     
    104120                return;
    105121
    106         free(info->name);
     122        free(info->cname);
    107123        free(info);
    108124}
  • uspace/lib/c/include/inet/dnsr.h

    racdb5bac r6e8ed225  
    3838#include <inet/inet.h>
    3939
     40enum {
     41        DNSR_NAME_MAX_SIZE = 255
     42};
     43
    4044typedef struct {
    41         /** Host name */
    42         char *name;
     45        /** Host canonical name */
     46        char *cname;
    4347        /** Host address */
    4448        inet_addr_t addr;
  • uspace/srv/net/dnsrsrv/dns_msg.c

    racdb5bac r6e8ed225  
    5050static uint16_t dns_uint16_t_decode(uint8_t *, size_t);
    5151
     52/** Extend dynamically allocated string with suffix.
     53 *
     54 * @a *dstr points to a dynamically alocated buffer containing a string.
     55 * Reallocate this buffer so that concatenation of @a *dstr and @a suff can
     56 * fit in and append @a suff.
     57 */
    5258static int dns_dstr_ext(char **dstr, const char *suff)
    5359{
     
    7783}
    7884
     85/** Encode DNS name.
     86 *
     87 * Encode DNS name or measure the size of encoded name (with @a buf NULL,
     88 * and @a buf_size 0).
     89 *
     90 * @param name          String to encode
     91 * @param buf           Buffer or NULL
     92 * @param buf_size      Buffer size or 0 if @a buf is NULL
     93 * @param act_size      Place to store actual encoded size
     94 */
    7995static int dns_name_encode(char *name, uint8_t *buf, size_t buf_size,
    8096    size_t *act_size)
     
    135151}
    136152
    137 static int dns_name_decode(uint8_t *buf, size_t size, size_t boff, char **rname,
     153/** Decode DNS name.
     154 *
     155 * @param pdu   PDU from which we are decoding
     156 * @param boff  Starting offset within PDU
     157 * @param rname Place to return dynamically allocated string
     158 * @param eoff  Place to store end offset (offset after last decoded byte)
     159 */
     160int dns_name_decode(dns_pdu_t *pdu, size_t boff, char **rname,
    138161    size_t *eoff)
    139162{
     
    151174        name = NULL;
    152175
    153         if (boff > size)
     176        if (boff > pdu->size)
    154177                return EINVAL;
    155178
    156         bp = buf + boff;
    157         bsize = min(size - boff, DNS_NAME_MAX_SIZE);
     179        bp = pdu->data + boff;
     180        bsize = min(pdu->size - boff, DNS_NAME_MAX_SIZE);
    158181        first = true;
    159182        *eoff = 0;
     
    192215                        --bsize;
    193216
    194                         if (ptr >= (size_t)(bp - buf)) {
     217                        if (ptr >= (size_t)(bp - pdu->data)) {
    195218                                log_msg(LOG_DEFAULT, LVL_DEBUG,
    196219                                    "Pointer- forward ref %zu, pos=%zu",
    197                                     ptr, (size_t)(bp - buf));
     220                                    ptr, (size_t)(bp - pdu->data));
    198221                                /* Forward reference */
    199222                                rc = EINVAL;
     
    205228                         * XXX Is assumption correct?
    206229                         */
    207                         eptr = bp - buf;
     230                        eptr = bp - pdu->data;
    208231                        /*
    209232                         * This is where encoded name ends in terms where
     
    212235                        *eoff = eptr;
    213236
    214                         bp = buf + ptr;
     237                        bp = pdu->data + ptr;
    215238                        bsize = eptr - ptr;
    216239                        continue;
     
    245268        *rname = name;
    246269        if (*eoff == 0)
    247                 *eoff = bp - buf;
     270                *eoff = bp - pdu->data;
    248271        return EOK;
    249272error:
     
    284307}
    285308
     309/** Encode DNS question.
     310 *
     311 * Encode DNS question or measure the size of encoded question (with @a buf NULL,
     312 * and @a buf_size 0).
     313 *
     314 * @param question      Question to encode
     315 * @param buf           Buffer or NULL
     316 * @param buf_size      Buffer size or 0 if @a buf is NULL
     317 * @param act_size      Place to store actual encoded size
     318 */
    286319static int dns_question_encode(dns_question_t *question, uint8_t *buf,
    287320    size_t buf_size, size_t *act_size)
     
    310343}
    311344
    312 static int dns_question_decode(uint8_t *buf, size_t buf_size, size_t boff,
     345/** Decode DNS question.
     346 *
     347 * @param pdu           PDU from which we are decoding
     348 * @param boff          Starting offset within PDU
     349 * @param rquestion     Place to return dynamically allocated question
     350 * @param eoff          Place to store end offset (offset after last decoded byte)
     351 */
     352static int dns_question_decode(dns_pdu_t *pdu, size_t boff,
    313353    dns_question_t **rquestion, size_t *eoff)
    314354{
     
    321361                return ENOMEM;
    322362
    323         rc = dns_name_decode(buf, buf_size, boff, &question->qname, &name_eoff);
     363        rc = dns_name_decode(pdu, boff, &question->qname, &name_eoff);
    324364        if (rc != EOK) {
    325365                log_msg(LOG_DEFAULT, LVL_DEBUG, "Error decoding name");
     
    328368        }
    329369
    330         if (name_eoff + 2 * sizeof(uint16_t) > buf_size) {
     370        if (name_eoff + 2 * sizeof(uint16_t) > pdu->size) {
    331371                free(question);
    332372                return EINVAL;
    333373        }
    334374
    335         question->qtype = dns_uint16_t_decode(buf + name_eoff, buf_size - name_eoff);
    336         question->qclass = dns_uint16_t_decode(buf + sizeof(uint16_t) + name_eoff,
    337             buf_size - sizeof(uint16_t) - name_eoff);
     375        question->qtype = dns_uint16_t_decode(pdu->data + name_eoff,
     376            pdu->size - name_eoff);
     377        question->qclass = dns_uint16_t_decode(pdu->data + sizeof(uint16_t)
     378            + name_eoff, pdu->size - sizeof(uint16_t) - name_eoff);
    338379        *eoff = name_eoff + 2 * sizeof(uint16_t);
    339380
     
    342383}
    343384
    344 static int dns_rr_decode(uint8_t *buf, size_t buf_size, size_t boff,
    345     dns_rr_t **retrr, size_t *eoff)
     385/** Decode DNS resource record.
     386 *
     387 * @param pdu           PDU from which we are decoding
     388 * @param boff          Starting offset within PDU
     389 * @param retrr         Place to return dynamically allocated resource record
     390 * @param eoff          Place to store end offset (offset after last decoded byte)
     391 */
     392static int dns_rr_decode(dns_pdu_t *pdu, size_t boff, dns_rr_t **retrr,
     393    size_t *eoff)
    346394{
    347395        dns_rr_t *rr;
     
    356404                return ENOMEM;
    357405
    358         rc = dns_name_decode(buf, buf_size, boff, &rr->name, &name_eoff);
     406        rc = dns_name_decode(pdu, boff, &rr->name, &name_eoff);
    359407        if (rc != EOK) {
    360408                log_msg(LOG_DEFAULT, LVL_DEBUG, "Error decoding name");
     
    363411        }
    364412
    365         if (name_eoff + 2 * sizeof(uint16_t) > buf_size) {
     413        if (name_eoff + 2 * sizeof(uint16_t) > pdu->size) {
    366414                free(rr->name);
    367415                free(rr);
     
    369417        }
    370418
    371         bp = buf + name_eoff;
    372         bsz = buf_size - name_eoff;
     419        bp = pdu->data + name_eoff;
     420        bsz = pdu->size - name_eoff;
    373421
    374422        if (bsz < 3 * sizeof(uint16_t) + sizeof(uint32_t)) {
     
    405453
    406454        memcpy(rr->rdata, bp, rdlength);
     455        rr->roff = bp - pdu->data;
    407456        bp += rdlength;
    408457        bsz -= rdlength;
    409458
    410         *eoff = bp - buf;
     459        *eoff = bp - pdu->data;
    411460        *retrr = rr;
    412461        return EOK;
    413462}
    414463
     464/** Encode DNS message.
     465 *
     466 * @param msg   Message
     467 * @param rdata Place to store encoded data pointer
     468 * @param rsize Place to store encoded data size
     469 *
     470 * @return      EOK on success, EINVAL if message contains invalid data,
     471 *              ENOMEM if out of memory
     472 */
    415473int dns_message_encode(dns_message_t *msg, void **rdata, size_t *rsize)
    416474{
     
    474532}
    475533
     534/** Decode DNS message.
     535 *
     536 * @param data  Encoded PDU data
     537 * @param size  Encoded PDU size
     538 * @param rmsg  Place to store pointer to decoded message
     539 *
     540 * @return      EOK on success, EINVAL if message contains invalid data,
     541 *              ENOMEM if out of memory
     542 */
    476543int dns_message_decode(void *data, size_t size, dns_message_t **rmsg)
    477544{
     
    491558                return ENOMEM;
    492559
    493         if (size < sizeof(dns_header_t))
    494                 return EINVAL;
     560        if (size < sizeof(dns_header_t)) {
     561                rc = EINVAL;
     562                goto error;
     563        }
     564
     565        /* Store a copy of raw message data for string decompression */
     566
     567        msg->pdu.data = malloc(size);
     568        if (msg->pdu.data == NULL) {
     569                rc = ENOMEM;
     570                goto error;
     571        }
     572
     573        memcpy(msg->pdu.data, data, size);
     574        msg->pdu.size = size;
     575        log_msg(LOG_DEFAULT, LVL_NOTE, "dns_message_decode: pdu->data = %p, "
     576            "pdu->size=%zu", msg->pdu.data, msg->pdu.size);
    495577
    496578        hdr = data;
     
    512594
    513595        for (i = 0; i < qd_count; i++) {
    514                 rc = dns_question_decode(data, size, doff, &question, &field_eoff);
     596                rc = dns_question_decode(&msg->pdu, doff, &question, &field_eoff);
    515597                if (rc != EOK) {
    516598                        log_msg(LOG_DEFAULT, LVL_DEBUG, "error decoding question");
     
    525607
    526608        for (i = 0; i < an_count; i++) {
    527                 rc = dns_rr_decode(data, size, doff, &rr, &field_eoff);
     609                rc = dns_rr_decode(&msg->pdu, doff, &rr, &field_eoff);
    528610                if (rc != EOK) {
    529611                        log_msg(LOG_DEFAULT, LVL_DEBUG, "Error decoding answer");
     
    542624}
    543625
     626/** Destroy question. */
    544627static void dns_question_destroy(dns_question_t *question)
    545628{
     
    548631}
    549632
     633/** Destroy resource record. */
    550634static void dns_rr_destroy(dns_rr_t *rr)
    551635{
     
    555639}
    556640
     641/** Create new empty message. */
    557642dns_message_t *dns_message_new(void)
    558643{
     
    571656}
    572657
     658/** Destroy message. */
    573659void dns_message_destroy(dns_message_t *msg)
    574660{
     
    605691        }
    606692
     693        free(msg->pdu.data);
    607694        free(msg);
    608695}
  • uspace/srv/net/dnsrsrv/dns_msg.h

    racdb5bac r6e8ed225  
    4747extern dns_message_t *dns_message_new(void);
    4848extern void dns_message_destroy(dns_message_t *);
     49extern int dns_name_decode(dns_pdu_t *, size_t, char **, size_t *);
    4950extern uint32_t dns_uint32_t_decode(uint8_t *, size_t);
    5051
  • uspace/srv/net/dnsrsrv/dns_type.h

    racdb5bac r6e8ed225  
    4343#include "dns_std.h"
    4444
    45 /** Unencoded DNS message */
     45/** Encoded DNS PDU */
    4646typedef struct {
     47        /** Encoded PDU data */
     48        uint8_t *data;
     49        /** Encoded PDU size */
     50        size_t size;
     51} dns_pdu_t;
     52
     53/** DNS message */
     54typedef struct {
     55        /* Encoded PDU */
     56        dns_pdu_t pdu;
     57
    4758        /** Identifier */
    4859        uint16_t id;
     
    95106        /** Number of bytes in @c *rdata */
    96107        size_t rdata_size;
     108        /** Offset in the raw message */
     109        size_t roff;
    97110} dns_rr_t;
    98111
     
    100113typedef struct {
    101114        /** Host name */
    102         char *name;
     115        char *cname;
    103116        /** Host address */
    104117        inet_addr_t addr;
  • uspace/srv/net/dnsrsrv/dnsrsrv.c

    racdb5bac r6e8ed225  
    8989        char *name;
    9090        dns_host_info_t *hinfo;
     91        ipc_callid_t rcallid;
     92        size_t size;
     93        sysarg_t retval;
     94        size_t act_size;
    9195        int rc;
    9296
     
    100104        }
    101105
     106        if (!async_data_read_receive(&rcallid, &size)) {
     107                async_answer_0(rcallid, EREFUSED);
     108                async_answer_0(callid, EREFUSED);
     109                return;
     110        }
     111
    102112        rc = dns_name2host(name, &hinfo);
    103113        if (rc != EOK) {
     114                async_answer_0(rcallid, rc);
    104115                async_answer_0(callid, rc);
    105116                return;
    106117        }
    107118
    108         async_answer_1(callid, EOK, hinfo->addr.ipv4);
     119        act_size = str_size(hinfo->cname);
     120        if (act_size > size) {
     121                async_answer_0(rcallid, EOVERFLOW);
     122                async_answer_0(callid, EOVERFLOW);
     123                return;
     124        }
     125
     126        retval = async_data_read_finalize(rcallid, hinfo->cname, act_size);
     127        async_answer_1(callid, retval, hinfo->addr.ipv4);
    109128
    110129        dns_hostinfo_destroy(hinfo);
  • uspace/srv/net/dnsrsrv/query.c

    racdb5bac r6e8ed225  
    5454        dns_question_t *question;
    5555        dns_host_info_t *info;
     56        char *sname, *cname;
     57        size_t eoff;
    5658        int rc;
    5759
     
    8385        }
    8486
     87        /* Start with the caller-provided name */
     88        sname = str_dup(name);
     89
    8590        list_foreach(amsg->answer, link) {
    8691                dns_rr_t *rr = list_get_instance(link, dns_rr_t, msg);
     
    8994                        rr->name, rr->rtype, rr->rclass, rr->rdata_size);
    9095
     96                if (rr->rtype == DTYPE_CNAME && rr->rclass == DC_IN &&
     97                    str_cmp(rr->name, sname) == 0) {
     98                        log_msg(LOG_DEFAULT, LVL_DEBUG, "decode cname (%p, %zu, %zu)",
     99                            amsg->pdu.data, amsg->pdu.size, rr->roff);
     100                        rc = dns_name_decode(&amsg->pdu, rr->roff, &cname, &eoff);
     101                        if (rc != EOK) {
     102                                log_msg(LOG_DEFAULT, LVL_DEBUG,
     103                                    "error decoding cname");
     104                                assert(rc == EINVAL || rc == ENOMEM);
     105                                dns_message_destroy(msg);
     106                                dns_message_destroy(amsg);
     107                                return rc;
     108                        }
     109
     110                        log_msg(LOG_DEFAULT, LVL_DEBUG, "name = '%s' "
     111                            "cname = '%s'", sname, cname);
     112
     113                        free(sname);
     114                        /* Continue looking for the more canonical name */
     115                        sname = cname;
     116                }
     117
    91118                if (rr->rtype == DTYPE_A && rr->rclass == DC_IN &&
    92                         rr->rdata_size == sizeof(uint32_t)) {
     119                        rr->rdata_size == sizeof(uint32_t) &&
     120                            str_cmp(rr->name, sname) == 0) {
    93121
    94122                        info = calloc(1, sizeof(dns_host_info_t));
    95123                        if (info == NULL) {
     124                                dns_message_destroy(msg);
    96125                                dns_message_destroy(amsg);
    97126                                return ENOMEM;
    98127                        }
    99128
    100                         info->name = str_dup(rr->name);
     129                        info->cname = str_dup(rr->name);
    101130                        info->addr.ipv4 = dns_uint32_t_decode(rr->rdata, rr->rdata_size);
    102                         log_msg(LOG_DEFAULT, LVL_DEBUG, "info->addr = %x",
    103                             info->addr.ipv4);
     131                        log_msg(LOG_DEFAULT, LVL_DEBUG, "info->name = '%s' "
     132                            "info->addr = %x", info->cname, info->addr.ipv4);
    104133
    105134                        dns_message_destroy(msg);
     
    112141        dns_message_destroy(msg);
    113142        dns_message_destroy(amsg);
    114         log_msg(LOG_DEFAULT, LVL_DEBUG, "No A/IN found, fail");
     143        log_msg(LOG_DEFAULT, LVL_DEBUG, "'%s' not resolved, fail", sname);
    115144
    116145        return EIO;
     
    119148void dns_hostinfo_destroy(dns_host_info_t *info)
    120149{
    121         free(info->name);
     150        free(info->cname);
    122151        free(info);
    123152}
  • uspace/srv/net/dnsrsrv/transport.c

    racdb5bac r6e8ed225  
    5454#define REQ_TIMEOUT (5*1000*1000)
    5555
     56/** Maximum number of retries */
     57#define REQ_RETRY_MAX 3
     58
    5659typedef struct {
    5760        link_t lreq;
     
    184187        struct sockaddr_in addr;
    185188        trans_req_t *treq;
     189        int ntry;
    186190
    187191        req_data = NULL;
     
    196200                goto error;
    197201
    198         rc = sendto(transport_fd, req_data, req_size, 0,
    199             (struct sockaddr *)&addr, sizeof(addr));
    200         if (rc != EOK)
    201                 goto error;
    202 
    203         treq = treq_create(req);
    204         if (treq == NULL) {
    205                 rc = ENOMEM;
    206                 goto error;
    207         }
    208 
    209         fibril_mutex_lock(&treq->done_lock);
    210         while (treq->done != true) {
    211                 rc = fibril_condvar_wait_timeout(&treq->done_cv, &treq->done_lock,
    212                     REQ_TIMEOUT);
    213                 if (rc == ETIMEOUT) {
    214                         fibril_mutex_unlock(&treq->done_lock);
    215                         rc = EIO;
     202        ntry = 0;
     203
     204        while (ntry < REQ_RETRY_MAX) {
     205                rc = sendto(transport_fd, req_data, req_size, 0,
     206                    (struct sockaddr *)&addr, sizeof(addr));
     207                if (rc != EOK)
     208                        goto error;
     209
     210                treq = treq_create(req);
     211                if (treq == NULL) {
     212                        rc = ENOMEM;
    216213                        goto error;
    217214                }
    218         }
    219 
    220         fibril_mutex_unlock(&treq->done_lock);
     215
     216
     217                fibril_mutex_lock(&treq->done_lock);
     218                while (treq->done != true) {
     219                        rc = fibril_condvar_wait_timeout(&treq->done_cv, &treq->done_lock,
     220                            REQ_TIMEOUT);
     221                        if (rc == ETIMEOUT) {
     222                                ++ntry;
     223                                break;
     224                        }
     225                }
     226
     227                fibril_mutex_unlock(&treq->done_lock);
     228
     229                if (rc != ETIMEOUT)
     230                        break;
     231        }
     232
     233        if (ntry >= REQ_RETRY_MAX) {
     234                rc = EIO;
     235                goto error;
     236        }
    221237
    222238        if (treq->status != EOK) {
Note: See TracChangeset for help on using the changeset viewer.