]> git.ipfire.org Git - thirdparty/bird.git/blobdiff - sysdep/unix/io.c
Merge branch 'master' into mq-filter-stack
[thirdparty/bird.git] / sysdep / unix / io.c
index cd2558b258741720780bfa82c12143e71c4c5f4f..c9fee3ab371d6a1368c2c1839b72150682214d30 100644 (file)
@@ -55,6 +55,7 @@
    this to gen small latencies */
 #define MAX_RX_STEPS 4
 
+
 /*
  *     Tracked Files
  */
@@ -89,17 +90,29 @@ static struct resclass rf_class = {
   NULL
 };
 
-void *
-tracked_fopen(pool *p, char *name, char *mode)
+struct rfile *
+rf_open(pool *p, char *name, char *mode)
 {
   FILE *f = fopen(name, mode);
 
-  if (f)
-    {
-      struct rfile *r = ralloc(p, &rf_class);
-      r->f = f;
-    }
-  return f;
+  if (!f)
+    return NULL;
+
+  struct rfile *r = ralloc(p, &rf_class);
+  r->f = f;
+  return r;
+}
+
+void *
+rf_file(struct rfile *f)
+{
+  return f->f;
+}
+
+int
+rf_fileno(struct rfile *f)
+{
+  return fileno(f->f);
 }
 
 
@@ -119,7 +132,7 @@ times_init(struct timeloop *loop)
   if (rv < 0)
     die("Monotonic clock is missing");
 
-  if ((ts.tv_sec < 0) || (((s64) ts.tv_sec) > ((s64) 1 << 40)))
+  if ((ts.tv_sec < 0) || (((u64) ts.tv_sec) > ((u64) 1 << 40)))
     log(L_WARN "Monotonic clock is crazy");
 
   loop->last_time = ts.tv_sec S + ts.tv_nsec NS;
@@ -958,10 +971,6 @@ sk_setup(sock *s)
 #endif
   }
 
-  if (s->priority >= 0)
-    if (sk_set_priority(s, s->priority) < 0)
-      return -1;
-
   if (sk_is_ipv4(s))
   {
     if (s->flags & SKF_LADDR_RX)
@@ -1012,6 +1021,11 @@ sk_setup(sock *s)
        return -1;
   }
 
+  /* Must be after sk_set_tos4() as setting ToS on Linux also mangles priority */
+  if (s->priority >= 0)
+    if (sk_set_priority(s, s->priority) < 0)
+      return -1;
+
   return 0;
 }
 
@@ -1063,10 +1077,12 @@ sk_passive_connected(sock *s, int type)
 
   sock *t = sk_new(s->pool);
   t->type = type;
+  t->data = s->data;
   t->af = s->af;
   t->fd = fd;
   t->ttl = s->ttl;
   t->tos = s->tos;
+  t->vrf = s->vrf;
   t->rbsize = s->rbsize;
   t->tbsize = s->tbsize;
 
@@ -1127,7 +1143,7 @@ sk_ssh_connect(sock *s)
     default:
       return SSH_ERROR;
     }
-  }
+  } /* fallthrough */
 
   case SK_SSH_SERVER_KNOWN:
   {
@@ -1174,7 +1190,7 @@ sk_ssh_connect(sock *s)
       if (!server_identity_is_ok)
        return SSH_ERROR;
     }
-  }
+  } /* fallthrough */
 
   case SK_SSH_USERAUTH:
   {
@@ -1190,7 +1206,7 @@ sk_ssh_connect(sock *s)
     default:
       return SSH_ERROR;
     }
-  }
+  } /* fallthrough */
 
   case SK_SSH_CHANNEL:
   {
@@ -1198,7 +1214,7 @@ sk_ssh_connect(sock *s)
     s->ssh->channel = ssh_channel_new(s->ssh->session);
     if (s->ssh->channel == NULL)
       return SSH_ERROR;
-  }
+  } /* fallthrough */
 
   case SK_SSH_SESSION:
   {
@@ -1214,7 +1230,7 @@ sk_ssh_connect(sock *s)
     default:
       return SSH_ERROR;
     }
-  }
+  } /* fallthrough */
 
   case SK_SSH_SUBSYSTEM:
   {
@@ -1233,7 +1249,7 @@ sk_ssh_connect(sock *s)
        return SSH_ERROR;
       }
     }
-  }
+  } /* fallthrough */
 
   case SK_SSH_ESTABLISHED:
     s->ssh->state = SK_SSH_ESTABLISHED;
@@ -1540,6 +1556,7 @@ sk_sendmsg(sock *s)
   struct iovec iov = {s->tbuf, s->tpos - s->tbuf};
   byte cmsg_buf[CMSG_TX_SPACE];
   sockaddr dst;
+  int flags = 0;
 
   sockaddr_fill(&dst, s->af, s->daddr, s->iface, s->dport);
 
@@ -1550,6 +1567,13 @@ sk_sendmsg(sock *s)
     .msg_iovlen = 1
   };
 
+#ifdef CONFIG_DONTROUTE_UNICAST
+  /* FreeBSD silently changes TTL to 1 when MSG_DONTROUTE is used, therefore we
+     cannot use it for other cases (e.g. when TTL security is used). */
+  if (ipa_is_ip4(s->daddr) && ip4_is_unicast(ipa_to_ip4(s->daddr)) && (s->ttl == 1))
+    flags = MSG_DONTROUTE;
+#endif
+
 #ifdef CONFIG_USE_HDRINCL
   byte hdr[20];
   struct iovec iov2[2] = { {hdr, 20}, iov };
@@ -1565,7 +1589,7 @@ sk_sendmsg(sock *s)
   if (s->flags & SKF_PKTINFO)
     sk_prepare_cmsgs(s, &msg, cmsg_buf, sizeof(cmsg_buf));
 
-  return sendmsg(s->fd, &msg, 0);
+  return sendmsg(s->fd, &msg, flags);
 }
 
 static inline int
@@ -2143,7 +2167,9 @@ io_init(void)
   // XXX init_times();
   // XXX update_times();
   boot_time = current_time();
-  srandom((uint) (current_real_time() TO_S));
+
+  u64 now = (u64) current_real_time();
+  srandom((uint) (now ^ (now >> 32)));
 }
 
 static int short_loops = 0;