diff options
| -rw-r--r-- | doc/man/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | doc/man/fccntl.3 | 119 | ||||
| -rw-r--r-- | doc/man/fqueue.3 | 2 | ||||
| -rw-r--r-- | include/ouroboros/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | include/ouroboros/fccntl.h | 67 | ||||
| -rw-r--r-- | include/ouroboros/fcntl.h | 59 | ||||
| -rw-r--r-- | include/ouroboros/frct_pci.h | 10 | ||||
| -rw-r--r-- | include/ouroboros/qos.h | 13 | ||||
| -rw-r--r-- | include/ouroboros/wrap/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | include/ouroboros/wrap/ouroboros.i | 4 | ||||
| -rw-r--r-- | src/lib/cdap.c | 1 | ||||
| -rw-r--r-- | src/lib/dev.c | 280 | ||||
| -rw-r--r-- | src/lib/frct_pci.c | 2 | ||||
| -rw-r--r-- | src/lib/qos.c | 6 | ||||
| -rw-r--r-- | src/tools/cbr/cbr_server.c | 4 | ||||
| -rw-r--r-- | src/tools/operf/operf_client.c | 4 | ||||
| -rw-r--r-- | src/tools/oping/oping_client.c | 4 | ||||
| -rw-r--r-- | src/tools/oping/oping_server.c | 2 | 
18 files changed, 339 insertions, 243 deletions
| diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index 280252ed..ab56242d 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -7,6 +7,7 @@ set(MAN_NAMES    flow_dealloc.3    flow_read.3    flow_write.3 +  fccntl.3    fqueue.3    fqueue_create.3    fqueue_destroy.3 diff --git a/doc/man/fccntl.3 b/doc/man/fccntl.3 new file mode 100644 index 00000000..20a1bf89 --- /dev/null +++ b/doc/man/fccntl.3 @@ -0,0 +1,119 @@ +.\" Ouroboros man pages (C) 2017 +.\" Dimitri Staessens <dimitri.staessens@ugent.be> +.\" Sander Vrijders <sander.vrijders@ugent.be> + +.TH FCCNTL 3 2017-08-30 GNU "Ouroboros Programmer's Manual" + +.SH NAME + +fccntl \- control commands for flows and FRCT connections + +.SH SYNOPSIS + +.B #include <ouroboros/fccntl.h> + +\fBint fccntl(int \fIfd\fB, int \fIcmd\fB, ...); + +Compile and link with \fI-louroboros\fR. + +.SH DESCRIPTION + +\fBfccntl\fR() is used to control the configuration of flows and +connections. + +Supported commands are: + +\fBFLOWSSNDTIMEO\fR - set the sender timeout. Takes a \fBstruct +timespec * \fItimeo\fR as third argument. Passing NULL for \fItimeo\fR +disables the timeout. + +\fBFLOWGSNDTIMEO\fR - retrieve the current sender timeout. Takes a +\fBstruct timespec * \fItimeo\fR as third argument. + +\fBFLOWSRCVTIMEO\fR - set the receiver timeout. Takes a \fBstruct +timespec * \fItimeo\fR as third argument. Passing NULL for \fItimeo\fR +disables the timeout. + +\fBFLOWGRCVTIMEO\fR - retrieve the current receiver timeout. Takes a +\fBstruct timespec * \fItimeo\fR as third argument. + +\fBFLOWGQOSSPEC\fR  - retrieve the current QoS specification of the +flow. Takes a \fBqosspec_t * \fIqs\fR as third argument. + +\fBFLOWSFLAGS\fR    - set flow flags. Takes flow flags as third +argument. Supported flags are: + +        \fIFLOWFRDONLY\fR   - set flow to read-only. + +        \fIFLOWFWRONLY\fR   - set flow_to write-only. + +        \fIFLOWFRDWR\fR     - set flow to read-write. + +        \fIFLOWFNONBLOCK\fR - set I/O to non-blocking. + +        \fIFLOWFDEFAULT\fR  - set flow defaults (blocking, read-write). + +\fBFLOWGFLAGS\fR    - get the current flow flags. Takes an \fBuint32_t +\fIflags\fR as third argument. + +\fBFRCTSFLAGS\fR    - set FRCT flags. Takes FRCT flags as third +argument. Supported flags are: + +        \fIFRCTFRESCNTRL\fR - enable resource control. + +        \fIFRCTFRTX\fR      - enable retransmission. + +        \fIFRCTFERRCHCK\fR  - enable checksum (CRC32). + +        \fIFRCTFORDERING\fR - enable packet in-order delivery. + +        \fIFRCTFPARTIAL\fR  - enable partial delivery. + +\fBFRCTGFLAGS\fR    - get the current flow flags. Takes an \fBuint16_t +\fIflags\fR as third argument. + +.SH RETURN VALUE + +On success, \fBfccntl\fR() returns 0. + +.SH ERRORS + +\fBfccntl\fR() can return + +.B -EINVAL +An invalid argument was passed. + +.B -EPERM +Operation not permitted. This is returned when requesting the value of +a timeout (FLOWGSNDTIMEO or FLOWGRCVTIMEO) when no such timeout was +set. + +.B -EBADF +Invalid flow descriptor passed. + +.B -ENOTALLOC +Flow is not allocated. + +.B -ENOTSUP +The specified command is not supported. + +.SH ATTRIBUTES + +For an explanation of the terms used in this section, see \fBattributes\fR(7). + +.TS +box, tab(&); +LB|LB|LB +L|L|L. +Interface & Attribute & Value +_ +\fBfccntl\fR() & Thread safety & MT-Safe +.TE + +.SH SEE ALSO + +.BR flow_alloc "(3), " flow_accept "(3), " flow_dealloc "(3), " fqueue (3) + +.SH COLOPHON +This page is part of the Ouroboros project, found at +https://bitbucket.org/ouroboros-rina/ouroboros diff --git a/doc/man/fqueue.3 b/doc/man/fqueue.3 index 611d54c7..cf8cef20 100644 --- a/doc/man/fqueue.3 +++ b/doc/man/fqueue.3 @@ -26,8 +26,6 @@ Compile and link with \fI-louroboros\fR.  .SH DESCRIPTION -These calls are used to -  The \fBfqueue_create\fR() function creates an fqueue_t structure which  is an event queue that stores events that occured within a certain  \fBfset_t\fR. diff --git a/include/ouroboros/CMakeLists.txt b/include/ouroboros/CMakeLists.txt index e39759fd..b6edac53 100644 --- a/include/ouroboros/CMakeLists.txt +++ b/include/ouroboros/CMakeLists.txt @@ -4,7 +4,7 @@ set(HEADER_FILES    cdefs.h    dev.h    errno.h -  fcntl.h +  fccntl.h    fqueue.h    ipcp.h    irm.h diff --git a/include/ouroboros/fccntl.h b/include/ouroboros/fccntl.h new file mode 100644 index 00000000..d938439f --- /dev/null +++ b/include/ouroboros/fccntl.h @@ -0,0 +1,67 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Flow and FRCT connection control + * + *    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_FCCNTL_H +#define OUROBOROS_FCCNTL_H + +#include <ouroboros/cdefs.h> + +#include <sys/time.h> + +/* Flow flags, same values as fcntl.h */ +#define FLOWFRDONLY   00000000 /* Read-only flow        */ +#define FLOWFWRONLY   00000001 /* Write-only flow       */ +#define FLOWFRDWR     00000002 /* Read-write flow       */ +#define FLOWFACCMODE  00000003 /* Access mask           */ + +#define FLOWFNONBLOCK 00004000 /* Non-blocking flow     */ +#define FLOWFDEFAULT  00000002 /* Default, blocking, rw */ + +#define FLOWFINVALID  (FLOWFWRONLY | FLOWFRDWR) + +/* FRCT flags */ +#define FRCTFRESCNTRL 00000001 /* Feedback from receiver */ +#define FRCTFRTX      00000002 /* Reliable flow          */ +#define FRCTFERRCHCK  00000004 /* Check for errors       */ +#define FRCTFORDERING 00000010 /* Ordered delivery       */ +#define FRCTFPARTIAL  00000020 /* Allow partial delivery */ + +/* Operations */ +#define FLOWSRCVTIMEO 00000001 /* Set read timeout       */ +#define FLOWGRCVTIMEO 00000002 /* Get read timeout       */ +#define FLOWSSNDTIMEO 00000003 /* Set send timeout       */ +#define FLOWGSNDTIMEO 00000004 /* Get send timeout       */ +#define FLOWGQOSSPEC  00000005 /* Get qosspec_t          */ +#define FLOWSFLAGS    00000006 /* Set flags for flow     */ +#define FLOWGFLAGS    00000007 /* Get flags for flow     */ +#define FRCTSFLAGS    00000010 /* Set flags for FRCT     */ +#define FRCTGFLAGS    00000011 /* Get flags for FRCT     */ + +__BEGIN_DECLS + +int fccntl(int fd, +           int cmd, +           ...); + +__END_DECLS + +#endif /* OUROBOROS_FCCNTL_H */ diff --git a/include/ouroboros/fcntl.h b/include/ouroboros/fcntl.h deleted file mode 100644 index 655a0a03..00000000 --- a/include/ouroboros/fcntl.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Flows - * - *    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_FCNTL_H -#define OUROBOROS_FCNTL_H - -#include <ouroboros/cdefs.h> - -#include <sys/time.h> - -/* same values as fcntl.h */ -#define FLOW_O_RDONLY   00000000 -#define FLOW_O_WRONLY   00000001 -#define FLOW_O_RDWR     00000002 -#define FLOW_O_ACCMODE  00000003 - -#define FLOW_O_NONBLOCK 00004000 -#define FLOW_O_DEFAULT  00000002 - -#define FLOW_O_INVALID  (FLOW_O_WRONLY | FLOW_O_RDWR) - -__BEGIN_DECLS - -int flow_set_flags(int fd, -                   int flags); - -int flow_get_flags(int fd); - -int flow_set_timeout(int                     fd, -                     const struct timespec * to); - -int flow_get_timeout(int               fd, -                     struct timespec * to); - -int flow_get_qosspec(int         fd, -                     qosspec_t * qs); - -__END_DECLS - -#endif /* OUROBOROS_FCNTL_H */ diff --git a/include/ouroboros/frct_pci.h b/include/ouroboros/frct_pci.h index 601c0ce4..a919bc60 100644 --- a/include/ouroboros/frct_pci.h +++ b/include/ouroboros/frct_pci.h @@ -35,7 +35,7 @@ struct frct_pci {          uint64_t seqno;          /* Present in config PDU. */ -        uint8_t  conf_flags; +        uint16_t conf_flags;          /* Present in flow control PDU. */          uint64_t lwe; @@ -51,14 +51,6 @@ enum pdu_types {          PDU_TYPE_RENDEZ_VOUS = 0x10  }; -enum config_flags { -        CONF_RESOURCE_CONTROL = 0x01, -        CONF_RELIABLE         = 0x02, -        CONF_ERROR_CHECK      = 0x04, -        CONF_ORDERED          = 0x08, -        CONF_PARTIAL          = 0x10 -}; -  enum data_flags {          FLAG_DATA_RUN       = 0x01,          FLAG_MORE_FRAGMENTS = 0x02 diff --git a/include/ouroboros/qos.h b/include/ouroboros/qos.h index f68df911..3d43dc31 100644 --- a/include/ouroboros/qos.h +++ b/include/ouroboros/qos.h @@ -31,15 +31,14 @@ typedef struct qos_spec {          uint64_t bandwidth;            /* In bits/s */          uint8_t  availability;         /* Class of 9s */          uint32_t maximum_interruption; /* In ms */ - -        bool     resource_control;     /* Feedback from receiver */ -        bool     reliable;             /* Reliable flow */ -        bool     error_check;          /* Check for errors */ -        bool     ordered;              /* Ordered delivery */ -        bool     partial;              /* Allow partial delivery */  } qosspec_t; +__BEGIN_DECLS +  int qosspec_init(qosspec_t * qs); +  int qosspec_fini(qosspec_t * qs); -#endif +__END_DECLS + +#endif /* OUROBOROS_QOS_H */ diff --git a/include/ouroboros/wrap/CMakeLists.txt b/include/ouroboros/wrap/CMakeLists.txt index 435b3b70..44c652d5 100644 --- a/include/ouroboros/wrap/CMakeLists.txt +++ b/include/ouroboros/wrap/CMakeLists.txt @@ -17,6 +17,8 @@ else ()      # Python assumes C99 since Python 3.6      test_and_set_c_compiler_flag_global(-std=c99) +    # SWIG generates code for varargs with an unused parameter +    test_and_set_c_compiler_flag_global(-Wno-unused-parameter)      # CMake > 3.8 deprecates swig_add_module      if (${CMAKE_VERSION} VERSION_LESS 3.8.0) diff --git a/include/ouroboros/wrap/ouroboros.i b/include/ouroboros/wrap/ouroboros.i index 4bf343b9..ebda2453 100644 --- a/include/ouroboros/wrap/ouroboros.i +++ b/include/ouroboros/wrap/ouroboros.i @@ -26,7 +26,7 @@  #include "ouroboros/cdap.h"  #include "ouroboros/dev.h"  #include "ouroboros/errno.h" -#include "ouroboros/fcntl.h" +#include "ouroboros/fccntl.h"  #include "ouroboros/fqueue.h"  #include "ouroboros/irm.h"  #include "ouroboros/ipcp.h" @@ -41,7 +41,7 @@ typedef int pid_t;  %include "ouroboros/cdap.h"  %include "ouroboros/dev.h"  %include "ouroboros/errno.h" -%include "ouroboros/fcntl.h" +%include "ouroboros/fccntl.h"  %include "ouroboros/fqueue.h"  %include "ouroboros/irm.h"  %include "ouroboros/ipcp.h" diff --git a/src/lib/cdap.c b/src/lib/cdap.c index 7d2feae3..d9cb2036 100644 --- a/src/lib/cdap.c +++ b/src/lib/cdap.c @@ -26,7 +26,6 @@  #include <ouroboros/bitmap.h>  #include <ouroboros/dev.h>  #include <ouroboros/fqueue.h> -#include <ouroboros/fcntl.h>  #include <ouroboros/errno.h>  #include "cdap_req.h" diff --git a/src/lib/dev.c b/src/lib/dev.c index d5044fb3..e02d66d0 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -29,7 +29,7 @@  #include <ouroboros/ipcp-dev.h>  #include <ouroboros/local-dev.h>  #include <ouroboros/sockets.h> -#include <ouroboros/fcntl.h> +#include <ouroboros/fccntl.h>  #include <ouroboros/bitmap.h>  #include <ouroboros/shm_flow_set.h>  #include <ouroboros/shm_rdrbuff.h> @@ -43,6 +43,7 @@  #include <stdlib.h>  #include <string.h>  #include <stdio.h> +#include <stdarg.h>  #define BUF_SIZE 1500 @@ -86,7 +87,7 @@ struct frcti {          uint64_t        rcv_lwe;          uint64_t        rcv_rwe; -        uint8_t         conf_flags; +        uint16_t        conf_flags;  };  struct port { @@ -108,7 +109,9 @@ struct flow {          pid_t                 api; -        bool                  timesout; +        bool                  snd_timesout; +        bool                  rcv_timesout; +        struct timespec       snd_timeo;          struct timespec       rcv_timeo;  }; @@ -309,7 +312,7 @@ static int frcti_send(int                  fd,          pci->seqno = frcti->snd_lwe++; -        if (frct_pci_ser(sdb, pci, frcti->conf_flags & CONF_ERROR_CHECK)) { +        if (frct_pci_ser(sdb, pci, frcti->conf_flags & FRCTFERRCHCK)) {                  pthread_rwlock_unlock(&ai.lock);                  return -1;          } @@ -325,8 +328,8 @@ static int frcti_send(int                  fd,  } -static int frcti_configure(int         fd, -                           qosspec_t * qos) +static int frcti_configure(int      fd, +                           uint16_t flags)  {          struct frcti *       frcti;          struct frct_pci      pci; @@ -336,22 +339,10 @@ static int frcti_configure(int         fd,          memset(&pci, 0, sizeof(pci)); -        if (qos == NULL) -                return 0; -          if (ipcp_sdb_reserve(&sdb, 0))                  return -1; -        if (qos->resource_control) -                pci.conf_flags |= CONF_RESOURCE_CONTROL; -        if (qos->reliable) -                pci.conf_flags |= CONF_RELIABLE; -        if (qos->error_check) -                pci.conf_flags |= CONF_ERROR_CHECK; -        if (qos->ordered) -                pci.conf_flags |= CONF_ORDERED; -        if (qos->partial) -                pci.conf_flags |= CONF_PARTIAL; +        pci.conf_flags = flags;          /* Always set the DRF on a configure message. */          pci.flags |= FLAG_DATA_RUN; @@ -385,49 +376,50 @@ static int frcti_write(int                  fd,  static ssize_t frcti_read(int fd)  { -        ssize_t              idx = -1; -        struct timespec      abstime; +        ssize_t              idx;          struct frcti *       frcti;          struct frct_pci      pci;          struct shm_du_buff * sdb; -        struct timespec      now = {0, 0};          do { -                pthread_rwlock_rdlock(&ai.lock); +                struct timespec    now; +                struct timespec    abs; +                struct timespec *  abstime = NULL; +                struct shm_rbuff * rb; +                bool               noblock; -                if (ai.flows[fd].oflags & FLOW_O_NONBLOCK) { -                        idx = shm_rbuff_read(ai.flows[fd].rx_rb); -                        pthread_rwlock_unlock(&ai.lock); -                } else { -                        struct shm_rbuff * rb   = ai.flows[fd].rx_rb; -                        bool timeo = ai.flows[fd].timesout; -                        struct timespec timeout = ai.flows[fd].rcv_timeo; +                clock_gettime(PTHREAD_COND_CLOCK, &now); -                        pthread_rwlock_unlock(&ai.lock); +                pthread_rwlock_rdlock(&ai.lock); + +                noblock = ai.flows[fd].oflags & FLOWFNONBLOCK; +                rb      = ai.flows[fd].rx_rb; -                        if (timeo) { -                                clock_gettime(PTHREAD_COND_CLOCK, &abstime); -                                ts_add(&abstime, &timeout, &abstime); -                                idx = shm_rbuff_read_b(rb, &abstime); -                        } else { -                                idx = shm_rbuff_read_b(rb, NULL); -                        } +                if (ai.flows[fd].rcv_timesout) { +                        ts_add(&now, &ai.flows[fd].rcv_timeo, &abs); +                        abstime = &abs;                  } +                pthread_rwlock_unlock(&ai.lock); + +                if (noblock) +                        idx = shm_rbuff_read(rb); +                else +                        idx = shm_rbuff_read_b(rb, abstime); +                  if (idx < 0)                          return idx;                  clock_gettime(CLOCK_REALTIME_COARSE, &now); -                pthread_rwlock_wrlock(&ai.lock); -                  frcti = &(ai.frcti[fd]);                  sdb = shm_rdrbuff_get(ai.rdrb, idx); +                pthread_rwlock_wrlock(&ai.lock); +                  /* SDU may be corrupted. */ -                if (frct_pci_des(sdb, &pci, -                                 frcti->conf_flags & CONF_ERROR_CHECK)) { +                if (frct_pci_des(sdb, &pci, frcti->conf_flags & FRCTFERRCHCK)) {                          pthread_rwlock_unlock(&ai.lock);                          shm_rdrbuff_remove(ai.rdrb, idx);                          return -EAGAIN; @@ -538,7 +530,7 @@ static int flow_init(int       port_id,          }          ai.flows[fd].port_id = port_id; -        ai.flows[fd].oflags  = FLOW_O_DEFAULT; +        ai.flows[fd].oflags  = FLOWFDEFAULT;          ai.flows[fd].api     = api;          ai.flows[fd].cube    = qc;          ai.flows[fd].spec    = qos_cube_to_spec(qc); @@ -821,7 +813,7 @@ int flow_alloc(const char *            dst_name,          pthread_rwlock_unlock(&ai.lock); -        if (frcti_configure(fd, qs)) { +        if (frcti_configure(fd, FRCTFORDERING | FRCTFERRCHCK)) {                  flow_fini(fd);                  bmp_release(ai.fds, fd);                  return -1; @@ -872,123 +864,113 @@ int flow_dealloc(int fd)          return 0;  } -int flow_set_flags(int fd, -                   int flags) +int fccntl(int fd, +           int cmd, +           ...)  { -        int old; +        uint32_t *        fflags; +        uint16_t *        cflags; +        va_list           l; +        struct timespec * timeo; +        qosspec_t *       qs;          if (fd < 0 || fd >= AP_MAX_FLOWS)                  return -EBADF; -        pthread_rwlock_wrlock(&ai.lock); - -        if (ai.flows[fd].port_id < 0) { -                pthread_rwlock_unlock(&ai.lock); -                return -ENOTALLOC; -        } - -        old = ai.flows[fd].oflags; - -        ai.flows[fd].oflags = flags; -        if (flags & FLOW_O_WRONLY) -                shm_rbuff_block(ai.flows[fd].rx_rb); -        if (flags & FLOW_O_RDWR) -                shm_rbuff_unblock(ai.flows[fd].rx_rb); - -        pthread_rwlock_unlock(&ai.lock); - -        return old; -} - -int flow_get_flags(int fd) -{ -        int old; - -        if (fd < 0 || fd >= AP_MAX_FLOWS) -                return -EBADF; +        va_start(l, cmd);          pthread_rwlock_wrlock(&ai.lock);          if (ai.flows[fd].port_id < 0) {                  pthread_rwlock_unlock(&ai.lock); +                va_end(l);                  return -ENOTALLOC;          } -        old = ai.flows[fd].oflags; - -        pthread_rwlock_unlock(&ai.lock); - -        return old; -} - -int flow_get_timeout(int               fd, -                     struct timespec * timeo) -{ -        int ret = 0; - -        if (fd < 0 || fd > AP_MAX_FLOWS || timeo == NULL) -                return -EINVAL; - -        pthread_rwlock_wrlock(&ai.lock); - -        if (ai.flows[fd].port_id < 0) { +        switch(cmd) { +        case FLOWSSNDTIMEO: +                timeo = va_arg(l, struct timespec *); +                if (timeo == NULL) { +                        ai.flows[fd].snd_timesout = false; +                } else { +                        ai.flows[fd].snd_timesout = true; +                        ai.flows[fd].snd_timeo    = *timeo; +                } +                break; +        case FLOWGSNDTIMEO: +                timeo = va_arg(l, struct timespec *); +                if (timeo == NULL) +                        goto einval; +                if (!ai.flows[fd].snd_timesout) +                        goto eperm; +                *timeo = ai.flows[fd].snd_timeo; +                break; +        case FLOWSRCVTIMEO: +                timeo = va_arg(l, struct timespec *); +                if (timeo == NULL) { +                        ai.flows[fd].rcv_timesout = false; +                } else { +                        ai.flows[fd].rcv_timesout = true; +                        ai.flows[fd].rcv_timeo    = *timeo; +                } +                break; +        case FLOWGRCVTIMEO: +                timeo = va_arg(l, struct timespec *); +                if (timeo == NULL) +                        goto einval; +                if (!ai.flows[fd].rcv_timesout) +                        goto eperm; +                *timeo = ai.flows[fd].snd_timeo; +                break; +        case FLOWGQOSSPEC: +                qs = va_arg(l, qosspec_t *); +                if (qs == NULL) +                        goto einval; +                *qs = ai.flows[fd].spec; +                break; +        case FLOWSFLAGS: +                ai.flows[fd].oflags = va_arg(l, uint32_t); +                if (ai.flows[fd].oflags & FLOWFWRONLY) +                        shm_rbuff_block(ai.flows[fd].rx_rb); +                if (ai.flows[fd].oflags & FLOWFRDWR) +                        shm_rbuff_unblock(ai.flows[fd].rx_rb); +                break; +        case FLOWGFLAGS: +                fflags = va_arg(l, uint32_t *); +                if (fflags == NULL) +                        goto einval; +                *fflags = ai.flows[fd].oflags; +                break; +        case FRCTSFLAGS: +                ai.frcti[fd].conf_flags = (uint16_t) va_arg(l, int); +                break; +        case FRCTGFLAGS: +                cflags = (uint16_t *) va_arg(l, int *); +                if (cflags == NULL) +                        goto einval; +                *cflags = ai.frcti[fd].conf_flags; +                break; +        default:                  pthread_rwlock_unlock(&ai.lock); -                return -ENOTALLOC; -        } +                va_end(l); +                return -ENOTSUP; -        if (ai.flows[fd].timesout) -                *timeo = ai.flows[fd].rcv_timeo; -        else -                ret = -EPERM; +        };          pthread_rwlock_unlock(&ai.lock); -        return ret; -} - -int flow_set_timeout(int                     fd, -                     const struct timespec * timeo) -{ -        if (fd < 0 || fd > AP_MAX_FLOWS) -                return -EINVAL; - -        pthread_rwlock_wrlock(&ai.lock); - -        if (ai.flows[fd].port_id < 0) { -                pthread_rwlock_unlock(&ai.lock); -                return -ENOTALLOC; -        } - -        if (timeo == NULL) { -                ai.flows[fd].timesout = false; -        } else { -                ai.flows[fd].timesout = true; -                ai.flows[fd].rcv_timeo = *timeo; -        } - -        pthread_rwlock_unlock(&ai.lock); +        va_end(l);          return 0; -} - -int flow_get_qosspec(int         fd, -                     qosspec_t * qs) -{ -        if (fd < 0 || fd > AP_MAX_FLOWS || qs == NULL) -                return -EINVAL; - -        pthread_rwlock_wrlock(&ai.lock); - -        if (ai.flows[fd].port_id < 0) { -                pthread_rwlock_unlock(&ai.lock); -                return -ENOTALLOC; -        } - -        *qs = ai.flows[fd].spec; + einval:          pthread_rwlock_unlock(&ai.lock); - -        return 0; +        va_end(l); +        return -EINVAL; + eperm: +        pthread_rwlock_unlock(&ai.lock); +        va_end(l); +        return -EPERM;  }  ssize_t flow_write(int          fd, @@ -1010,12 +992,12 @@ ssize_t flow_write(int          fd,                  return -ENOTALLOC;          } -        if ((ai.flows[fd].oflags & FLOW_O_ACCMODE) == FLOW_O_RDONLY) { +        if ((ai.flows[fd].oflags & FLOWFACCMODE) == FLOWFRDONLY) {                  pthread_rwlock_unlock(&ai.lock);                  return -EPERM;          } -        if (ai.flows[fd].oflags & FLOW_O_NONBLOCK) { +        if (ai.flows[fd].oflags & FLOWFNONBLOCK) {                  idx = shm_rdrbuff_write(ai.rdrb,                                         DU_BUFF_HEADSPACE,                                         DU_BUFF_TAILSPACE, @@ -1062,10 +1044,11 @@ ssize_t flow_read(int    fd,                    void * buf,                    size_t count)  { -        ssize_t   idx = -1; -        ssize_t   n; -        uint8_t * sdu; -        bool      used; +        ssize_t            idx; +        ssize_t            n; +        uint8_t *          sdu; +        bool               used; +        struct shm_rbuff * rb;          if (fd < 0 || fd > AP_MAX_FLOWS)                  return -EBADF; @@ -1078,11 +1061,12 @@ ssize_t flow_read(int    fd,          }          used = ai.frcti[fd].used; +        rb   = ai.flows[fd].rx_rb;          pthread_rwlock_unlock(&ai.lock);          if (!used) -                idx = shm_rbuff_read(ai.flows[fd].rx_rb); +                idx = shm_rbuff_read(rb);          else                  idx = frcti_read(fd); @@ -1477,7 +1461,7 @@ int ipcp_flow_write(int                  fd,                  return -ENOTALLOC;          } -        if ((ai.flows[fd].oflags & FLOW_O_ACCMODE) == FLOW_O_RDONLY) { +        if ((ai.flows[fd].oflags & FLOWFACCMODE) == FLOWFRDONLY) {                  pthread_rwlock_unlock(&ai.lock);                  return -EPERM;          } @@ -1527,7 +1511,7 @@ void ipcp_flow_fini(int fd)  {          struct shm_rbuff * rx_rb; -        flow_set_flags(fd, FLOW_O_WRONLY); +        fccntl(fd, FLOWSFLAGS, FLOWFWRONLY);          pthread_rwlock_rdlock(&ai.lock); diff --git a/src/lib/frct_pci.c b/src/lib/frct_pci.c index 4fa9ddc2..e44554f2 100644 --- a/src/lib/frct_pci.c +++ b/src/lib/frct_pci.c @@ -30,7 +30,7 @@  #define TYPE_SIZE       1  #define SEQNO_SIZE      8  #define FLAGS_SIZE      1 -#define CONF_FLAGS_SIZE 1 +#define CONF_FLAGS_SIZE sizeof(((struct frct_pci *) NULL)->conf_flags)  #define BASE_SIZE       TYPE_SIZE + FLAGS_SIZE + SEQNO_SIZE  #define CONFIG_SIZE     CONF_FLAGS_SIZE diff --git a/src/lib/qos.c b/src/lib/qos.c index 35e16f97..09866c4e 100644 --- a/src/lib/qos.c +++ b/src/lib/qos.c @@ -36,12 +36,6 @@ int qosspec_init(qosspec_t * qs)          qs->availability = 0;          qs->maximum_interruption = UINT32_MAX; -        qs->resource_control = true; -        qs->reliable = false; -        qs->error_check = true; -        qs->ordered = true; -        qs->partial = false; -          return 0;  } diff --git a/src/tools/cbr/cbr_server.c b/src/tools/cbr/cbr_server.c index a2e930e5..b25b09e8 100644 --- a/src/tools/cbr/cbr_server.c +++ b/src/tools/cbr/cbr_server.c @@ -22,7 +22,7 @@  #include <ouroboros/dev.h>  #include <ouroboros/time_utils.h> -#include <ouroboros/fcntl.h> +#include <ouroboros/fccntl.h>  #include <stdbool.h> @@ -84,7 +84,7 @@ static void handle_flow(int fd)          alive = iv_start;          ts_add(&iv_start, &intv, &iv_end); -        flow_set_flags(fd, FLOW_O_NONBLOCK); +        fccntl(fd, FLOWSFLAGS, FLOWFNONBLOCK);          while (!stop) {                  clock_gettime(CLOCK_REALTIME, &now); diff --git a/src/tools/operf/operf_client.c b/src/tools/operf/operf_client.c index 4ad26d13..df486380 100644 --- a/src/tools/operf/operf_client.c +++ b/src/tools/operf/operf_client.c @@ -21,7 +21,7 @@   */  #include <ouroboros/dev.h> -#include <ouroboros/fcntl.h> +#include <ouroboros/fccntl.h>  #include <ouroboros/time_utils.h>  #include <signal.h> @@ -68,7 +68,7 @@ void * reader(void * o)          int fd = *((int *) o);          int msg_len = 0; -        flow_set_timeout(fd, &timeout); +        fccntl(fd, FLOWSRCVTIMEO, &timeout);          while ((msg_len = flow_read(fd, buf, OPERF_BUF_SIZE)) != -ETIMEDOUT) {                  if (msg_len != client.size) { diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c index db0ef199..ca8c0e72 100644 --- a/src/tools/oping/oping_client.c +++ b/src/tools/oping/oping_client.c @@ -21,7 +21,7 @@   */  #include <ouroboros/dev.h> -#include <ouroboros/fcntl.h> +#include <ouroboros/fccntl.h>  #include <ouroboros/time_utils.h>  #include <signal.h> @@ -60,7 +60,7 @@ void * reader(void * o)          double ms = 0;          double d = 0; -        flow_set_timeout(fd, &timeout); +        fccntl(fd, FLOWSRCVTIMEO, &timeout);          while (client.rcvd != client.count) {                  msg_len = flow_read(fd, buf, OPING_BUF_SIZE); diff --git a/src/tools/oping/oping_server.c b/src/tools/oping/oping_server.c index 6a535caf..0371f90f 100644 --- a/src/tools/oping/oping_server.c +++ b/src/tools/oping/oping_server.c @@ -130,7 +130,7 @@ void * accept_thread(void * o)                  server.times[fd] = now;                  pthread_mutex_unlock(&server.lock); -                flow_set_flags(fd, FLOW_O_NONBLOCK | FLOW_O_RDWR); +                fccntl(fd, FLOWSFLAGS, FLOWFNONBLOCK | FLOWFRDWR);          }          return (void *) 0; | 
