From 4060efec26115dbb9e68da67bc482a12b4f80ea8 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Wed, 30 Aug 2017 17:11:22 +0200 Subject: lib: Add fccntl configuration command This replaces the flow_set_* commands with a single fccntl command that can configure flows and the FRCT instance. For more details, see "man 3 fccntl". --- doc/man/CMakeLists.txt | 1 + doc/man/fccntl.3 | 119 +++++++++++++++ doc/man/fqueue.3 | 2 - include/ouroboros/CMakeLists.txt | 2 +- include/ouroboros/fccntl.h | 67 ++++++++ include/ouroboros/fcntl.h | 59 ------- include/ouroboros/frct_pci.h | 10 +- include/ouroboros/qos.h | 13 +- include/ouroboros/wrap/CMakeLists.txt | 2 + include/ouroboros/wrap/ouroboros.i | 4 +- src/lib/cdap.c | 1 - src/lib/dev.c | 280 ++++++++++++++++------------------ src/lib/frct_pci.c | 2 +- src/lib/qos.c | 6 - src/tools/cbr/cbr_server.c | 4 +- src/tools/operf/operf_client.c | 4 +- src/tools/oping/oping_client.c | 4 +- src/tools/oping/oping_server.c | 2 +- 18 files changed, 339 insertions(+), 243 deletions(-) create mode 100644 doc/man/fccntl.3 create mode 100644 include/ouroboros/fccntl.h delete mode 100644 include/ouroboros/fcntl.h 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 +.\" Sander Vrijders + +.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 + +\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 + * Sander Vrijders + * + * 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 + +#include + +/* 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 - * Sander Vrijders - * - * 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 - -#include - -/* 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 #include #include -#include #include #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 #include #include -#include +#include #include #include #include @@ -43,6 +43,7 @@ #include #include #include +#include #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 #include -#include +#include #include @@ -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 -#include +#include #include #include @@ -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 -#include +#include #include #include @@ -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; -- cgit v1.2.3