summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/man/fccntl.32
-rw-r--r--doc/man/flow_read.35
-rw-r--r--include/ouroboros/fccntl.h1
-rw-r--r--src/ipcpd/normal/pol/link_state.c8
-rw-r--r--src/lib/dev.c20
5 files changed, 25 insertions, 11 deletions
diff --git a/doc/man/fccntl.3 b/doc/man/fccntl.3
index 34e63e7d..bec506ec 100644
--- a/doc/man/fccntl.3
+++ b/doc/man/fccntl.3
@@ -58,6 +58,8 @@ argument. Supported flags are:
\fIFLOWFNONBLOCK\fR - set I/O to non-blocking read/write.
+\fIFLOWFRNOPART\fR - disable partial reading.
+
\fIFLOWFDEFAULT\fR - set flow defaults (blocking, read-write).
.RE
diff --git a/doc/man/flow_read.3 b/doc/man/flow_read.3
index 0110d0a2..20f5b976 100644
--- a/doc/man/flow_read.3
+++ b/doc/man/flow_read.3
@@ -33,15 +33,14 @@ On success, \fBflow_read\fR() returns the number of bytes read. On
failure, a negative value indicating the error will be returned. If
the number of bytes read equals count, a subsequent call to
\fBflow_read\fR() should be performed to check if there were more
-bytes to read. This call to \fBflow_read\fR will return 0 if there
-was no more data and mark the end of the datagram.
+bytes to read. This call to \fBflow_read\fR will return 0 if there was
+no more data and mark the end of the datagram.
On success, \fBflow_write\fR() returns 0. On failure, a negative value
indicating the error will be returned. Passing a NULL pointer for
\fIbuf\fR returns 0 with no other effects.
.SH ERRORS
-
.B -EINVAL
An invalid argument was passed.
diff --git a/include/ouroboros/fccntl.h b/include/ouroboros/fccntl.h
index 8940e6ef..5c3fc064 100644
--- a/include/ouroboros/fccntl.h
+++ b/include/ouroboros/fccntl.h
@@ -38,6 +38,7 @@
#define FLOWFRNOBLOCK 00001000 /* Non-blocking read */
#define FLOWFWNOBLOCK 00002000 /* Non-blocking write */
#define FLOWFNONBLOCK (FLOWFRNOBLOCK | FLOWFWNOBLOCK)
+#define FLOWFRNOPART 00004000 /* Disable partial reads */
#define FLOWFDEFAULT FLOWFRDWR
diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c
index 7aa7faf7..cfe4faff 100644
--- a/src/ipcpd/normal/pol/link_state.c
+++ b/src/ipcpd/normal/pol/link_state.c
@@ -29,6 +29,7 @@
#include <ouroboros/endian.h>
#include <ouroboros/dev.h>
#include <ouroboros/errno.h>
+#include <ouroboros/fccntl.h>
#include <ouroboros/fqueue.h>
#include <ouroboros/list.h>
#include <ouroboros/logs.h>
@@ -655,7 +656,7 @@ static void * lsreader(void * o)
{
fqueue_t * fq;
int ret;
- uint8_t buf[sizeof(struct lsa) + 1];
+ uint8_t buf[sizeof(struct lsa)];
int fd;
qosspec_t qs;
struct lsa * msg;
@@ -680,7 +681,7 @@ static void * lsreader(void * o)
}
while ((fd = fqueue_next(fq)) >= 0) {
- len = flow_read(fd, buf, sizeof(*msg) + 1);
+ len = flow_read(fd, buf, sizeof(*msg));
if (len <= 0 || len != sizeof(*msg))
continue;
@@ -724,6 +725,7 @@ static void handle_event(void * self,
/* FIXME: Apply correct QoS on graph */
struct conn * c;
qosspec_t qs;
+ int flags;
(void) self;
@@ -759,6 +761,8 @@ static void handle_event(void * self,
flow_event(c->flow_info.fd, false);
break;
case NOTIFY_MGMT_CONN_ADD:
+ fccntl(c->flow_info.fd, FLOWGFLAGS, &flags);
+ fccntl(c->flow_info.fd, FLOWSFLAGS, flags | FLOWFRNOPART);
fset_add(ls.mgmt_set, c->flow_info.fd);
if (lsdb_add_nb(c->conn_info.addr, c->flow_info.fd, NB_MGMT))
log_warn("Failed to add mgmt neighbor to LSDB.");
diff --git a/src/lib/dev.c b/src/lib/dev.c
index 115cd565..d0766783 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -897,6 +897,7 @@ ssize_t flow_read(int fd,
struct timespec * abstime = NULL;
struct flow * flow;
bool noblock;
+ bool partrd;
if (fd < 0 || fd > PROG_MAX_FLOWS)
return -EBADF;
@@ -919,6 +920,7 @@ ssize_t flow_read(int fd,
rb = flow->rx_rb;
noblock = flow->oflags & FLOWFRNOBLOCK;
+ partrd = !(flow->oflags & FLOWFRNOPART);
if (ai.flows[fd].rcv_timesout) {
ts_add(&abs, &flow->rcv_timeo, &abs);
@@ -948,14 +950,20 @@ ssize_t flow_read(int fd,
if (n <= (ssize_t) count) {
memcpy(buf, sdu, n);
shm_rdrbuff_remove(ai.rdrb, idx);
- flow->part_idx = (n == (ssize_t) count) ? DONE_PART : NO_PART;
+ flow->part_idx = (partrd && n == (ssize_t) count) ?
+ DONE_PART : NO_PART;
return n;
} else {
- memcpy(buf, sdu, count);
- sdb = shm_rdrbuff_get(ai.rdrb, idx);
- shm_du_buff_head_release(sdb, n);
- flow->part_idx = idx;
- return count;
+ if (partrd) {
+ memcpy(buf, sdu, count);
+ sdb = shm_rdrbuff_get(ai.rdrb, idx);
+ shm_du_buff_head_release(sdb, n);
+ flow->part_idx = idx;
+ return count;
+ } else {
+ shm_rdrbuff_remove(ai.rdrb, idx);
+ return -EMSGSIZE;
+ }
}
}