diff options
-rw-r--r-- | doc/man/fccntl.3 | 2 | ||||
-rw-r--r-- | doc/man/flow_read.3 | 5 | ||||
-rw-r--r-- | include/ouroboros/fccntl.h | 1 | ||||
-rw-r--r-- | src/ipcpd/normal/pol/link_state.c | 8 | ||||
-rw-r--r-- | src/lib/dev.c | 20 |
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; + } } } |