summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2016-10-16 09:38:01 +0200
committerdimitri staessens <[email protected]>2016-10-16 10:05:19 +0200
commitc79ab46894053312f80390bf13a52c238a7d4704 (patch)
tree038cbefec387fc15af2dd0b8325b063977a08590 /src
parentb8b05e3b1980146ab8acb40cbe77e0271634c688 (diff)
downloadouroboros-c79ab46894053312f80390bf13a52c238a7d4704.tar.gz
ouroboros-c79ab46894053312f80390bf13a52c238a7d4704.zip
lib, dev: Implement read/write options for flows
Added the missing implementation of setting read/write options for flows. This allows applications to block the fast path for remotes. IPCPs can use this to block the fast path for the N + 1 flow when receiving remote deallocation requests.
Diffstat (limited to 'src')
-rw-r--r--src/ipcpd/local/main.c2
-rw-r--r--src/lib/dev.c17
2 files changed, 19 insertions, 0 deletions
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index b8b3335c..4e500a8a 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -24,6 +24,7 @@
#include "ipcp.h"
#include <ouroboros/errno.h>
#include <ouroboros/dev.h>
+#include <ouroboros/fcntl.h>
#include <ouroboros/select.h>
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/local-dev.h>
@@ -252,6 +253,7 @@ static int ipcp_local_flow_dealloc(int fd)
pthread_rwlock_rdlock(&ipcpi.state_lock);
pthread_rwlock_wrlock(&local_data.lock);
+ flow_cntl(local_data.in_out[fd], FLOW_F_SETFL, FLOW_O_WRONLY);
local_data.in_out[fd] = -1;
pthread_rwlock_unlock(&local_data.lock);
diff --git a/src/lib/dev.c b/src/lib/dev.c
index a3082a7d..77c2d06a 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -561,6 +561,7 @@ int flow_dealloc(int fd)
ai.flows[fd].port_id = -1;
shm_ap_rbuff_close(ai.flows[fd].rb);
ai.flows[fd].rb = NULL;
+ ai.flows[fd].oflags = 0;
ai.flows[fd].api = -1;
if (ai.flows[fd].timeout != NULL) {
free(ai.flows[fd].timeout);
@@ -602,6 +603,10 @@ int flow_cntl(int fd, int cmd, int oflags)
return old;
case FLOW_F_SETFL: /* SET FLOW FLAGS */
ai.flows[fd].oflags = oflags;
+ if (oflags & FLOW_O_WRONLY)
+ shm_ap_rbuff_close_port(ai.rb, ai.flows[fd].port_id);
+ if (oflags & FLOW_O_RDWR)
+ shm_ap_rbuff_open_port(ai.rb, ai.flows[fd].port_id);
pthread_rwlock_unlock(&ai.flows_lock);
pthread_rwlock_unlock(&ai.data_lock);
return old;
@@ -632,6 +637,12 @@ ssize_t flow_write(int fd, void * buf, size_t count)
return -ENOTALLOC;
}
+ if (ai.flows[fd].oflags & FLOW_O_RDONLY) {
+ pthread_rwlock_unlock(&ai.flows_lock);
+ pthread_rwlock_unlock(&ai.data_lock);
+ return -EPERM;
+ }
+
if (ai.flows[fd].oflags & FLOW_O_NONBLOCK) {
idx = shm_rdrbuff_write(ai.rdrb,
ai.flows[fd].api,
@@ -1078,6 +1089,12 @@ int ipcp_flow_write(int fd, struct shm_du_buff * sdb)
pthread_rwlock_rdlock(&ai.data_lock);
pthread_rwlock_rdlock(&ai.flows_lock);
+ if (ai.flows[fd].oflags & FLOW_O_RDONLY) {
+ pthread_rwlock_unlock(&ai.flows_lock);
+ pthread_rwlock_unlock(&ai.data_lock);
+ return -EPERM;
+ }
+
if (ai.flows[fd].rb == NULL) {
pthread_rwlock_unlock(&ai.flows_lock);
pthread_rwlock_unlock(&ai.data_lock);