diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2022-02-25 17:34:29 +0100 | 
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2022-03-03 12:00:54 +0100 | 
| commit | f5d642a06f9c1a58197313b32f6b213a152e446f (patch) | |
| tree | 19ec9813f2d83fae986ff2bddbf5511c5b7662da /src/lib/dev.c | |
| parent | db5e9bf4f884097ec919aa40b02d8eafab05cfa8 (diff) | |
| download | ouroboros-f5d642a06f9c1a58197313b32f6b213a152e446f.tar.gz ouroboros-f5d642a06f9c1a58197313b32f6b213a152e446f.zip  | |
lib: Make flow liveness timeout configurable
The qosspec_t now has a timeout value that sets the timeout value of
the flow. Flows with a peer that has timed out will now return
-EFLOWPEER on flow_read() or flow_write().
Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks>
Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/lib/dev.c')
| -rw-r--r-- | src/lib/dev.c | 66 | 
1 files changed, 46 insertions, 20 deletions
diff --git a/src/lib/dev.c b/src/lib/dev.c index 4c21fcdf..5c57a538 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -68,7 +68,6 @@  #define SECMEMSZ  16384  #define SYMMKEYSZ 32  #define MSGBUFSZ  2048 -#define FLOWTIMEO 120 /* seconds */  enum port_state {          PORT_NULL = 0, @@ -123,7 +122,8 @@ struct flow_set_entry {  struct flow_set {          size_t idx; -        struct timespec  chk;   /* Last keepalive check */ +        struct timespec  chk;   /* Last keepalive check.          */ +        uint32_t         min;   /* Minimum keepalive time in set. */          struct list_head flows;          pthread_rwlock_t lock; @@ -1056,6 +1056,7 @@ static int flow_keepalive(int fd)          struct timespec    r_act;          struct flow *      flow;          int                flow_id; +        uint32_t           timeo;          flow = &ai.flows[fd]; @@ -1067,15 +1068,19 @@ static int flow_keepalive(int fd)          r_act = flow->rcv_act;          flow_id = flow->flow_id; +        timeo   = flow->qs.timeout;          pthread_rwlock_unlock(&ai.lock); -        if (ts_diff_ns(&r_act, &now) > FLOWTIMEO * BILLION) { -                shm_flow_set_notify(ai.fqset, flow_id, FLOW_PKT); -                return -EFLOWDOWN; +        if (timeo == 0) +                return 0; + +        if (ts_diff_ns(&r_act, &now) > timeo * MILLION) { +                shm_flow_set_notify(ai.fqset, flow_id, FLOW_PEER); +                return -EFLOWPEER;          } -        if (ts_diff_ns(&s_act, &now) > (FLOWTIMEO / 4) * BILLION) +        if (ts_diff_ns(&s_act, &now) > (timeo >> 2) * MILLION)                  flow_send_keepalive(fd);          return 0; @@ -1140,7 +1145,7 @@ ssize_t flow_write(int          fd,                                  return -ETIMEDOUT;                          if (flow_keepalive(fd)) -                                return -EFLOWDOWN; +                                return -EFLOWPEER;                          frcti_tick(flow->frcti); @@ -1165,14 +1170,16 @@ ssize_t flow_write(int          fd,          pthread_rwlock_rdlock(&ai.lock); -        if (count != 0 && frcti_snd(flow->frcti, sdb) < 0) -                goto enomem; +        if (count > 0) { +                if (frcti_snd(flow->frcti, sdb) < 0) +                        goto enomem; -        if (flow->qs.cypher_s > 0 && crypt_encrypt(flow, sdb) < 0) -                goto enomem; +                if (flow->qs.cypher_s > 0 && crypt_encrypt(flow, sdb) < 0) +                        goto enomem; -        if (flow->qs.ber == 0 && add_crc(sdb) != 0) -                goto enomem; +                if (flow->qs.ber == 0 && add_crc(sdb) != 0) +                        goto enomem; +        }          pthread_cleanup_push(__cleanup_rwlock_unlock, &ai.lock); @@ -1263,7 +1270,7 @@ ssize_t flow_read(int    fd,                                          return -ETIMEDOUT;                                  if (flow_keepalive(fd) < 0) -                                        return -EFLOWDOWN; +                                        return -EFLOWPEER;                                  ts_add(&tictime, &tic, &tictime); @@ -1360,6 +1367,7 @@ struct flow_set * fset_create()                  goto fail_bmp_alloc;          set->chk = now; +        set->min = UINT32_MAX;          pthread_rwlock_unlock(&ai.lock); @@ -1437,6 +1445,7 @@ void fset_zero(struct flow_set * set)  int fset_add(struct flow_set * set,               int               fd)  { +        struct flow *           flow;          struct flow_set_entry * fse;          int                     ret;          size_t                  packets; @@ -1445,13 +1454,17 @@ int fset_add(struct flow_set * set,          if (set == NULL || fd < 0 || fd >= SYS_MAX_FLOWS)                  return -EINVAL; +        flow = &ai.flows[fd]; +          fse = malloc(sizeof(*fse));          if (fse == NULL)                  return -ENOMEM; -        pthread_rwlock_wrlock(&ai.lock); +        fse->fd = fd; -        if (ai.flows[fd].flow_id < 0) { +        pthread_rwlock_rdlock(&ai.lock); + +        if (flow->flow_id < 0) {                  ret = -EINVAL;                  goto fail;          } @@ -1462,6 +1475,9 @@ int fset_add(struct flow_set * set,          pthread_rwlock_wrlock(&set->lock); +        if (flow->qs.timeout != 0 && flow->qs.timeout < set->min) +                set->min = flow->qs.timeout; +          list_add_tail(&fse->next, &set->flows);          pthread_rwlock_unlock(&set->lock); @@ -1485,14 +1501,20 @@ void fset_del(struct flow_set * set,  {          struct list_head * p;          struct list_head * h; +        struct flow *      flow; +        uint32_t           min;          if (set == NULL || fd < 0 || fd >= SYS_MAX_FLOWS)                  return; +        flow = &ai.flows[fd]; + +        min = UINT32_MAX; +          pthread_rwlock_rdlock(&ai.lock); -        if (ai.flows[fd].flow_id >= 0) -                shm_flow_set_del(ai.fqset, set->idx, ai.flows[fd].flow_id); +        if (flow->flow_id >= 0) +                shm_flow_set_del(ai.fqset, set->idx, flow->flow_id);          pthread_rwlock_wrlock(&set->lock); @@ -1502,10 +1524,14 @@ void fset_del(struct flow_set * set,                  if (e->fd == fd) {                          list_del(&e->next);                          free(e); -                        break; +                } else { +                        if (flow->qs.timeout != 0 && flow->qs.timeout < min) +                                min = flow->qs.timeout;                  }          } +        set->min = min; +          pthread_rwlock_unlock(&set->lock);          pthread_rwlock_unlock(&ai.lock); @@ -1544,7 +1570,7 @@ static void fset_keepalive(struct flow_set * set)          pthread_rwlock_wrlock(&set->lock); -        if (ts_diff_ns(&now, &set->chk) < (FLOWTIMEO / 4) * BILLION) { +        if (ts_diff_ns(&now, &set->chk) < set->min >> 2) {                  pthread_rwlock_unlock(&set->lock);                  return;          }  | 
