linux.c, yaid.c, yaid.h: Open the NAT table just once at init time.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 18 Oct 2012 09:35:35 +0000 (10:35 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 21 Oct 2012 15:08:58 +0000 (16:08 +0100)
This file requires privileges to open, so it must be done before we
drop them.  (We don't, yet, but it's coming.)

linux.c
yaid.c
yaid.h

diff --git a/linux.c b/linux.c
index 15db30b..4954cf9 100644 (file)
--- a/linux.c
+++ b/linux.c
 
 /*----- Static variables --------------------------------------------------*/
 
+static FILE *natfp;
+
+/*----- Address-type operations -------------------------------------------*/
+
 struct addrops_sys {
   const char *procfile;
   int (*parseaddr)(char **, union addr *);
@@ -238,27 +242,17 @@ void identify(struct query *q)
   }
 
   if (ferror(fp)) {
-    logmsg(q, LOG_ERR, "failed to read connection table: %s",
-          strerror(errno));
+    logmsg(q, LOG_ERR, "failed to read connection table `%s': %s",
+          q->ao->sys->procfile, strerror(errno));
     goto err_unk;
   }
 
-  if (q->ao->af == AF_INET) {
-    fclose(fp);
-    if ((fp = fopen("/proc/net/ip_conntrack", "r")) == 0) {
-      if (errno == ENOENT)
-       goto err_nouser;
-      else {
-       logmsg(q, LOG_ERR,
-              "failed to open `/proc/net/ip_conntrack' for reading: %s",
-              strerror(errno));
-       goto err_unk;
-      }
-    }
+  if (natfp && q->ao->af == AF_INET) {
+    rewind(natfp);
 
     for (;;) {
       DRESET(&d);
-      if (dstr_putline(&d, fp) == EOF) break;
+      if (dstr_putline(&d, natfp) == EOF) break;
       pp = d.buf;
       NEXTFIELD; if (!*p) break;
       if (strcmp(p, "tcp") != 0) continue;
@@ -319,17 +313,16 @@ void identify(struct query *q)
       goto done;
     }
 
-    if (ferror(fp)) {
+    if (ferror(natfp)) {
       logmsg(q, LOG_ERR, "failed to read `/proc/net/ip_conntrack': %s",
             strerror(errno));
       goto err_unk;
     }
-    logmsg(q, LOG_ERR, "connection not found");
   }
 
 #undef NEXTFIELD
 
-err_nouser:
+  logmsg(q, LOG_NOTICE, "connection not found");
   q->resp = R_ERROR;
   q->u.error = E_NOUSER;
   goto done;
@@ -341,4 +334,13 @@ done:
   if (fp) fclose(fp);
 }
 
+void init_sys(void)
+{
+  if ((natfp = fopen("/proc/net/ip_conntrack", "r")) == 0 &&
+      errno != ENOENT) {
+    die(1, "failed to open `/proc/net/ip_conntrack' for reading: %s",
+       strerror(errno));
+  }
+}
+
 /*----- That's all, folks -------------------------------------------------*/
diff --git a/yaid.c b/yaid.c
index f70c2a3..661b984 100644 (file)
--- a/yaid.c
+++ b/yaid.c
@@ -623,6 +623,7 @@ int main(int argc, char *argv[])
   ego(argv[0]);
 
   fwatch_init(&polfw, "yaid.policy");
+  init_sys();
   if (load_policy_file("yaid.policy", &policy))
     exit(1);
   { int i;
diff --git a/yaid.h b/yaid.h
index f8f6470..80aa98b 100644 (file)
--- a/yaid.h
+++ b/yaid.h
@@ -238,6 +238,7 @@ void dputsock(dstr *d, const struct addrops *ao, const struct socket *s);
 void logmsg(const struct query *q, int prio, const char *msg, ...);
 
 void identify(struct query *q);
+void init_sys(void);
 
 void init_policy(struct policy *p);
 void free_policy(struct policy *p);