diff options
| -rw-r--r-- | include/ouroboros/shm_du_buff.h | 4 | ||||
| -rw-r--r-- | src/lib/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/lib/dev.c | 3 | ||||
| -rw-r--r-- | src/lib/frct.c | 177 | ||||
| -rw-r--r-- | src/lib/frct_pci.c | 129 | ||||
| -rw-r--r-- | src/lib/frct_pci.h | 67 | ||||
| -rw-r--r-- | src/lib/shm_rdrbuff.c | 22 | 
7 files changed, 142 insertions, 261 deletions
diff --git a/include/ouroboros/shm_du_buff.h b/include/ouroboros/shm_du_buff.h index c558f378..04e17cf4 100644 --- a/include/ouroboros/shm_du_buff.h +++ b/include/ouroboros/shm_du_buff.h @@ -40,10 +40,10 @@ uint8_t * shm_du_buff_head_alloc(struct shm_du_buff * sdb,  uint8_t * shm_du_buff_tail_alloc(struct shm_du_buff * sdb,                                   size_t               size); -void      shm_du_buff_head_release(struct shm_du_buff * sdb, +uint8_t * shm_du_buff_head_release(struct shm_du_buff * sdb,                                     size_t               size); -void      shm_du_buff_tail_release(struct shm_du_buff * sdb, +uint8_t * shm_du_buff_tail_release(struct shm_du_buff * sdb,                                     size_t               size);  void      shm_du_buff_truncate(struct shm_du_buff * sdb, diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index ba670acf..3531ac27 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -174,7 +174,6 @@ set(SOURCE_FILES_DEV    # Add source files here    cacep.c    dev.c -  frct_pci.c    timerwheel.c    ) diff --git a/src/lib/dev.c b/src/lib/dev.c index ff22cca6..e80bf9f9 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -24,6 +24,7 @@  #include "config.h" +#include <ouroboros/hash.h>  #include <ouroboros/errno.h>  #include <ouroboros/dev.h>  #include <ouroboros/ipcp-dev.h> @@ -31,6 +32,7 @@  #include <ouroboros/sockets.h>  #include <ouroboros/fccntl.h>  #include <ouroboros/bitmap.h> +#include <ouroboros/random.h>  #include <ouroboros/shm_flow_set.h>  #include <ouroboros/shm_rdrbuff.h>  #include <ouroboros/shm_rbuff.h> @@ -39,7 +41,6 @@  #include <ouroboros/qoscube.h>  #include <ouroboros/timerwheel.h> -#include "frct_pci.h"  #include "rq.h"  #include <stdlib.h> diff --git a/src/lib/frct.c b/src/lib/frct.c index abebb2ff..5f45f522 100644 --- a/src/lib/frct.c +++ b/src/lib/frct.c @@ -30,16 +30,20 @@  #define TW_ELEMENTS    6000  #define TW_RESOLUTION  1     /* ms */ +#define FRCT_PCILEN    (sizeof(struct frct_pci)) +#define FRCT_CRCLEN    (sizeof(uint32_t)) +  struct frct_cr { -        bool            drf; -        uint64_t        lwe; -        uint64_t        rwe; +        bool     drf; +        uint32_t lwe; +        uint32_t rwe; -        bool            conf; -        uint16_t        cflags; +        uint32_t seqno; +        bool     conf; +        uint8_t  cflags; -        time_t          act; -        time_t          inact; +        time_t   act; +        time_t   inact;  };  struct frcti { @@ -63,6 +67,28 @@ struct {          struct timerwheel * tw;  } frct; +enum frct_flags { +        FRCT_DATA = 0x01, /* PDU carries data */ +        FRCT_DRF  = 0x02, /* Data run flag    */ +        FRCT_ACK  = 0x03, /* ACK field valid  */ +        FRCT_FC   = 0x08, /* FC window valid  */ +        FRCT_RDVZ = 0x10, /* Rendez-vous      */ +        FRCT_CFG  = 0x20, /* Configuration    */ +        FRCT_MFGM = 0x40, /* More fragments   */ +        FRCT_CRC  = 0x80, /* CRC present      */ +}; + +struct frct_pci { +        uint8_t  flags; + +        uint8_t  cflags; + +        uint16_t window; + +        uint32_t seqno; +        uint32_t ackno; +} __attribute__((packed)); +  static int frct_init(void)  {          frct.tw = timerwheel_create(TW_RESOLUTION, TW_RESOLUTION * TW_ELEMENTS); @@ -104,6 +130,11 @@ static struct frcti * frcti_create(int fd)          frcti->snd_cr.drf    = true;          frcti->snd_cr.conf   = true; +#ifdef OUROBOROS_CONFIG_DEBUG +        frcti->snd_cr.seqno  = 0; +#else +        random_buffer(&frcti->snd_cr.seqno, sizeof(frcti->snd_cr.seqno)); +#endif          frcti->snd_cr.lwe    = 0;          frcti->snd_cr.rwe    = 0;          frcti->snd_cr.cflags = 0; @@ -201,44 +232,79 @@ static ssize_t __frcti_queued_pdu(struct frcti * frcti)          return idx;  } +static int frct_chk_crc(uint8_t * head, +                        uint8_t * tail) +{ +        uint32_t crc; + +        mem_hash(HASH_CRC32, &crc, head, tail - head); + +        return crc == *((uint32_t *) tail); +} + +static void frct_add_crc(uint8_t * head, +                         uint8_t * tail) +{ +        mem_hash(HASH_CRC32, tail, head, tail - head); +} + +static struct frct_pci * frcti_alloc_head(struct shm_du_buff * sdb) +{ +        struct frct_pci * pci = NULL; + +        pci = (struct frct_pci *) shm_du_buff_head_alloc(sdb, FRCT_PCILEN); +        if (pci != NULL) +                memset(pci, 0, sizeof(*pci)); + +        return pci; +} +  static int __frcti_snd(struct frcti *       frcti,                         struct shm_du_buff * sdb)  { -        struct frct_pci  pci; -        struct timespec  now; -        struct frct_cr * snd_cr; +        struct frct_pci * pci; +        struct timespec   now; +        struct frct_cr *  snd_cr; -        if (frcti == NULL) -                return 0; +        assert(frcti);          snd_cr = &frcti->snd_cr; -        memset(&pci, 0, sizeof(pci)); +        pci = frcti_alloc_head(sdb); +        if (pci == NULL) +                return -1;          clock_gettime(CLOCK_REALTIME_COARSE, &now); -        pci.type |= PDU_TYPE_DATA; -          pthread_rwlock_wrlock(&frcti->lock);          /* Check if sender is inactive. */          if (!snd_cr->drf && now.tv_sec - snd_cr->act > snd_cr->inact)                  snd_cr->drf = true; +        pci->flags |= FRCT_DATA; +          /* Set the DRF in the first packet of a new run of SDUs. */          if (snd_cr->drf) { -                pci.flags |= FLAG_DATA_RUN; +                pci->flags |= FRCT_DRF;                  if (snd_cr->conf) { -                        pci.type |= PDU_TYPE_CONFIG; -                        pci.cflags = snd_cr->cflags; +                        pci->flags |= FRCT_CFG; +                        pci->cflags = snd_cr->cflags;                  }          } -        pci.seqno = snd_cr->lwe++; +        pci->seqno = snd_cr->seqno++; -        if (frct_pci_ser(sdb, &pci, snd_cr->cflags & FRCTFERRCHCK)) { -                pthread_rwlock_unlock(&frcti->lock); -                return -1; +        if (snd_cr->cflags & FRCTFERRCHCK) { +                uint8_t * tail = shm_du_buff_tail_alloc(sdb, FRCT_CRCLEN); +                if (tail == NULL) { +                        pthread_rwlock_unlock(&frcti->lock); +                        return -1; +                } + +                frct_add_crc((uint8_t *) pci, tail); + +                pci->flags |= FRCT_CRC;          }          snd_cr->act = now.tv_sec; @@ -255,44 +321,55 @@ static int __frcti_snd(struct frcti *       frcti,  static int __frcti_rcv(struct frcti *       frcti,                         struct shm_du_buff * sdb)  { -        ssize_t          idx; -        struct frct_pci  pci; -        struct timespec  now; -        struct frct_cr * rcv_cr; +        ssize_t           idx; +        struct frct_pci * pci; +        struct timespec   now; +        struct frct_cr *  rcv_cr;          assert(frcti);          rcv_cr = &frcti->rcv_cr; +        pci = (struct frct_pci *) shm_du_buff_head_release(sdb, FRCT_PCILEN); +          clock_gettime(CLOCK_REALTIME_COARSE, &now);          pthread_rwlock_wrlock(&frcti->lock);          idx = shm_du_buff_get_idx(sdb); -        /* SDU may be corrupted. */ -        if (frct_pci_des(sdb, &pci, rcv_cr->cflags & FRCTFERRCHCK)) { -                pthread_rwlock_unlock(&frcti->lock); -                shm_rdrbuff_remove(ai.rdrb, idx); -                return -EAGAIN; +        /* PDU may be corrupted. */ +        if (pci->flags & FRCT_CRC) { +                uint8_t * tail = shm_du_buff_tail_release(sdb, FRCT_CRCLEN); +                if (frct_chk_crc((uint8_t *) pci, tail)) +                        goto fail_clean;          }          /* Check if receiver inactivity is true. */          if (!rcv_cr->drf && now.tv_sec - rcv_cr->act > rcv_cr->inact)                  rcv_cr->drf = true; -        /* When there is receiver inactivity and no DRF, drop the SDU. */ -        if (rcv_cr->drf && !(pci.flags & FLAG_DATA_RUN)) { -                pthread_rwlock_unlock(&frcti->lock); -                shm_rdrbuff_remove(ai.rdrb, idx); -                return -EAGAIN; +        /* When there is receiver inactivity and no DRF, drop the PDU. */ +        if (rcv_cr->drf && !(pci->flags & FRCT_DRF)) +                goto fail_clean; + +        /* Queue the PDU if needed. */ +        if (rcv_cr->cflags & FRCTFORDERING) { +                if (pci->seqno != frcti->rcv_cr.lwe) { +                        /* NOTE: queued PDUs head/tail without PCI. */ +                        if (rq_push(frcti->rq, pci->seqno, idx)) +                                shm_rdrbuff_remove(ai.rdrb, idx); +                        goto fail; +                } else { +                      ++rcv_cr->lwe; +                }          }          /* If the DRF is set, reset the state of the connection. */ -        if (pci.flags & FLAG_DATA_RUN) { -                rcv_cr->lwe = pci.seqno; -                if (pci.type & PDU_TYPE_CONFIG) -                        rcv_cr->cflags = pci.cflags; +        if (pci->flags & FRCT_DRF) { +                rcv_cr->lwe = pci->seqno; +                if (pci->flags & FRCT_CFG) +                        rcv_cr->cflags = pci->cflags;          }          if (rcv_cr->drf) @@ -300,21 +377,17 @@ static int __frcti_rcv(struct frcti *       frcti,          rcv_cr->act = now.tv_sec; -        if (!(pci.type & PDU_TYPE_DATA)) +        if (!(pci->flags & FRCT_DATA))                  shm_rdrbuff_remove(ai.rdrb, idx); -        if (rcv_cr->cflags & FRCTFORDERING) { -                if (pci.seqno != frcti->rcv_cr.lwe) { -                        if (rq_push(frcti->rq, pci.seqno, idx)) -                                shm_rdrbuff_remove(ai.rdrb, idx); -                        pthread_rwlock_unlock(&frcti->lock); -                        return -EAGAIN; -                } else { -                      ++rcv_cr->lwe; -                } -        } -          pthread_rwlock_unlock(&frcti->lock);          return 0; + + fail_clean: +        if (!(pci->flags & FRCT_DATA)) +                shm_rdrbuff_remove(ai.rdrb, idx); + fail: +        pthread_rwlock_unlock(&frcti->lock); +        return -EAGAIN;  } diff --git a/src/lib/frct_pci.c b/src/lib/frct_pci.c deleted file mode 100644 index 509cc8e2..00000000 --- a/src/lib/frct_pci.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Protocol Control Information of FRCT - * - *    Dimitri Staessens <dimitri.staessens@ugent.be> - *    Sander Vrijders   <sander.vrijders@ugent.be> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#include <ouroboros/hash.h> -#include <ouroboros/errno.h> - -#include "frct_pci.h" - -#include <assert.h> -#include <string.h> - -#define TYPE_SIZE        1 -#define FLAGS_SIZE       1 -#define SEQNO_SIZE       8 -#define CONF_FLAGS_SIZE  2 - -#define BASE_SIZE        TYPE_SIZE + FLAGS_SIZE + SEQNO_SIZE - -#define head_len(pci)    (pci->type & PDU_TYPE_CONFIG ?                 \ -                          BASE_SIZE + CONF_FLAGS_SIZE : BASE_SIZE) - -int frct_pci_ser(struct shm_du_buff * sdb, -                 struct frct_pci *    pci, -                 bool                 error_check) -{ -        uint8_t * head; -        uint8_t * tail; -        size_t    offset = 0; - -        assert(sdb); -        assert(pci); - -        head = shm_du_buff_head_alloc(sdb, head_len(pci)); -        if (head == NULL) -                return -EPERM; - -        memcpy(head, &pci->type, TYPE_SIZE); -        offset += TYPE_SIZE; -        memcpy(head + offset, &pci->flags, FLAGS_SIZE); -        offset += FLAGS_SIZE; -        memcpy(head + offset, &pci->seqno, SEQNO_SIZE); -        offset += SEQNO_SIZE; - -        if (pci->type & PDU_TYPE_CONFIG) { -                memcpy(head + offset, &pci->cflags, CONF_FLAGS_SIZE); -                /* offset += CONF_FLAGS_SIZE; */ -        } - -        if (error_check) { -                tail = shm_du_buff_tail_alloc(sdb, hash_len(HASH_CRC32)); -                if (tail == NULL) { -                        shm_du_buff_head_release(sdb, head_len(pci)); -                        return -EPERM; -                } - -                *((uint32_t *) tail) = 0; -                mem_hash(HASH_CRC32, (uint32_t *) tail, head, tail - head); -        } - -        return 0; -} - -int frct_pci_des(struct shm_du_buff * sdb, -                 struct frct_pci *    pci, -                 bool                 error_check) -{ -        uint8_t * head; -        uint8_t * tail; -        uint32_t  crc; -        uint32_t  crc2; -        size_t    offset = 0; - -        assert(sdb); -        assert(pci); - -        head = shm_du_buff_head(sdb); - -        if (error_check) { -                tail = shm_du_buff_tail(sdb); - -                mem_hash(HASH_CRC32, &crc, head, -                         tail - head - hash_len(HASH_CRC32)); - -                memcpy(&crc2, tail - hash_len(HASH_CRC32), -                       hash_len(HASH_CRC32)); - -                /* Corrupted SDU. */ -                if (crc != crc2) -                        return -1; - -                shm_du_buff_tail_release(sdb, hash_len(HASH_CRC32)); -        } - -        /* Depending on the type a different deserialization. */ -        memcpy(&pci->type, head, TYPE_SIZE); -        offset += TYPE_SIZE; -        memcpy(&pci->flags, head + offset, FLAGS_SIZE); -        offset += FLAGS_SIZE; -        memcpy(&pci->seqno, head + offset, SEQNO_SIZE); -        offset += SEQNO_SIZE; - -        if (pci->type & PDU_TYPE_CONFIG) { -                memcpy(&pci->cflags, head + offset, CONF_FLAGS_SIZE); -                /* offset += CONF_FLAGS_SIZE; */ -        } - -        shm_du_buff_head_release(sdb, head_len(pci)); - -        return 0; -} diff --git a/src/lib/frct_pci.h b/src/lib/frct_pci.h deleted file mode 100644 index fbbfd354..00000000 --- a/src/lib/frct_pci.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Protocol Control Information of FRCT - * - *    Dimitri Staessens <dimitri.staessens@ugent.be> - *    Sander Vrijders   <sander.vrijders@ugent.be> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#ifndef OUROBOROS_LIB_FRCT_PCI_H -#define OUROBOROS_LIB_FRCT_PCI_H - -#include <ouroboros/shm_du_buff.h> - -#include <stdint.h> -#include <stdbool.h> - -struct frct_pci { -        /* Present in every PDU. */ -        uint8_t  type; -        uint8_t  flags; -        uint64_t seqno; - -        /* Present in config PDU. */ -        uint16_t cflags; - -        /* Present in flow control PDU. */ -        uint64_t lwe; -        uint64_t rwe; -}; - -enum pdu_types { -        PDU_TYPE_DATA        = 0x01, -        PDU_TYPE_ACK         = 0x02, -        PDU_TYPE_FC          = 0x04, -        PDU_TYPE_ACK_AND_FC  = (PDU_TYPE_ACK | PDU_TYPE_FC), -        PDU_TYPE_RENDEZ_VOUS = 0x08, -        PDU_TYPE_CONFIG      = 0x10 -}; - -enum data_flags { -        FLAG_DATA_RUN       = 0x01, -        FLAG_MORE_FRAGMENTS = 0x02 -}; - -int frct_pci_ser(struct shm_du_buff * sdb, -                 struct frct_pci *    pci, -                 bool                 error_check); - -int frct_pci_des(struct shm_du_buff * sdb, -                 struct frct_pci *    pci, -                 bool                 error_check); - -#endif /* OUROBOROS_LIB_FRCT_PCI_H */ diff --git a/src/lib/shm_rdrbuff.c b/src/lib/shm_rdrbuff.c index a3333a35..2853d5bb 100644 --- a/src/lib/shm_rdrbuff.c +++ b/src/lib/shm_rdrbuff.c @@ -602,8 +602,6 @@ uint8_t * shm_du_buff_tail(struct shm_du_buff * sdb)  uint8_t * shm_du_buff_head_alloc(struct shm_du_buff * sdb,                                   size_t               size)  { -        uint8_t * buf = NULL; -          assert(sdb);          if (sdb->du_head < size) @@ -611,15 +609,13 @@ uint8_t * shm_du_buff_head_alloc(struct shm_du_buff * sdb,          sdb->du_head -= size; -        buf = (uint8_t *) (sdb + 1) + sdb->du_head; - -        return buf; +        return (uint8_t *) (sdb + 1) + sdb->du_head;  }  uint8_t * shm_du_buff_tail_alloc(struct shm_du_buff * sdb,                                   size_t               size)  { -        uint8_t * buf = NULL; +        uint8_t * buf;          assert(sdb); @@ -633,22 +629,30 @@ uint8_t * shm_du_buff_tail_alloc(struct shm_du_buff * sdb,          return buf;  } -void shm_du_buff_head_release(struct shm_du_buff * sdb, -                              size_t               size) +uint8_t * shm_du_buff_head_release(struct shm_du_buff * sdb, +                                   size_t               size)  { +        uint8_t * buf; +          assert(sdb);          assert(!(size > sdb->du_tail - sdb->du_head)); +        buf = (uint8_t *) (sdb + 1) + sdb->du_head; +          sdb->du_head += size; + +        return buf;  } -void shm_du_buff_tail_release(struct shm_du_buff * sdb, +uint8_t * shm_du_buff_tail_release(struct shm_du_buff * sdb,                                size_t               size)  {          assert(sdb);          assert(!(size > sdb->du_tail - sdb->du_head));          sdb->du_tail -= size; + +        return (uint8_t *) (sdb + 1) + sdb->du_tail;  }  void shm_du_buff_truncate(struct shm_du_buff * sdb,  | 
