Prechádzať zdrojové kódy

* Use mmap for GET_CHECKSUM and GET_CONF, WRITE_CHECKSUM is next

svn: 3803
Bryan Drewery 18 rokov pred
rodič
commit
ed1dbb7877
2 zmenil súbory, kde vykonal 64 pridanie a 37 odobranie
  1. 61 34
      src/binary.c
  2. 3 3
      src/main.c

+ 61 - 34
src/binary.c

@@ -20,7 +20,10 @@
 
 #include <sys/wait.h>
 #include <sys/types.h>
+#include <sys/mman.h>
 #include <signal.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 settings_t settings = {
   "\200\200\200\200\200\200\200\200\200\200\200\200\200\200\200",
@@ -33,12 +36,28 @@ settings_t settings = {
 };
 
 static void edpack(settings_t *, const char *, int);
+#ifdef DEBUG
+static void tellconfig(settings_t *);
+#endif
 
 #define PACK_ENC 1
 #define PACK_DEC 2
 
 int checked_bin_buf = 0;
 
+#define MMAP_LOOP(_offset, _block_len, _total) 		\
+  for ((_offset) = 0; 					\
+       (_offset) < (_total); 				\
+       (_offset) += (_block_len),			\
+        len = ((_total) - (_offset)) < (_block_len) ? 	\
+              ((_total) - (_offset)) : 			\
+              (_block_len)				\
+      )
+
+#define MMAP_READ(_map, _dest, _offset, _len)	\
+  memcpy((_dest), &(_map)[(_offset)], (_len));	\
+  (_offset) += (_len);
+
 static char *
 bin_checksum(const char *fname, int todo)
 {
@@ -46,57 +65,66 @@ bin_checksum(const char *fname, int todo)
   static char hash[MD5_HASH_LENGTH + 1] = "";
   unsigned char md5out[MD5_HASH_LENGTH + 1] = "", buf[PREFIXLEN + 1] = "";
   FILE *f = NULL;
-  size_t len = 0;
+  int fd = -1;
+  size_t len = 0, offset = 0, size = 0;
+  unsigned char *map = NULL;
 
   MD5_Init(&ctx);
 
-  checked_bin_buf++;
+  ++checked_bin_buf;
  
   hash[0] = 0;
 
   fixmod(fname);
 
   if (todo == GET_CHECKSUM) {
-    if (!(f = fopen(fname, "rb")))
-      werr(ERR_BINSTAT);
-
-    while ((len = fread(buf, 1, sizeof buf - 1, f))) {
-      if (!memcmp(buf, &settings.prefix, PREFIXLEN))
+    fd = open(fname, O_RDONLY);
+    if (fd == -1) werr(ERR_BINSTAT);
+    size = lseek(fd, 0, SEEK_END);
+    map = (unsigned char*) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
+    MMAP_LOOP(offset, sizeof(buf) - 1, size) {
+      if (!memcmp(&map[offset], &settings.prefix, PREFIXLEN))
         break;
-      MD5_Update(&ctx, buf, len);
     }
-
-    fclose(f);
-    f = NULL;
+    MD5_Update(&ctx, map, offset);
+    munmap(map, size);
+    close(fd);
     MD5_Final(md5out, &ctx);
     strlcpy(hash, btoh(md5out, MD5_DIGEST_LENGTH), sizeof(hash));
     OPENSSL_cleanse(&ctx, sizeof(ctx));
   }
 
   if (todo == GET_CONF) {
-    char *oldhash = strdup(settings.hash);
+    fd = open(fname, O_RDONLY);
+    if (fd == -1) werr(ERR_BINSTAT);
+    size = lseek(fd, 0, SEEK_END);
+    map = (unsigned char*) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
+
+    /* Find the packdata */
+    MMAP_LOOP(offset, sizeof(buf) - 1, size) {
+      if (!memcmp(&map[offset], &settings.prefix, PREFIXLEN))
+        break;
+    }
+    MD5_Update(&ctx, map, offset);
+    MD5_Final(md5out, &ctx);
+    strlcpy(hash, btoh(md5out, MD5_DIGEST_LENGTH), sizeof(hash));
+    OPENSSL_cleanse(&ctx, sizeof(ctx));
 
-    if (!(f = fopen(fname, "rb")))
-      werr(ERR_BINSTAT);
+    settings_t newsettings;
 
-    while ((len = fread(buf, 1, sizeof buf - 1, f)))
-      if (!memcmp(buf, &settings.prefix, PREFIXLEN))
-        break;
+    /* Read the settings struct into newsettings */
+    MMAP_READ(map, &newsettings, offset, sizeof(settings));
+
+    /* Decrypt the new data */
+    edpack(&newsettings, hash, PACK_DEC);
+    OPENSSL_cleanse(hash, sizeof(hash));
+
+    /* Copy over only the dynamic data, leaving the pack config static */
+    memcpy(&settings.bots, &newsettings.bots, SIZE_CONF);
+
+    munmap(map, size);
+    close(fd);
 
-    char *tmpbuf = (char *) my_calloc(1, SIZE_PACK);
- 
-    if ((len = fread(tmpbuf, 1, SIZE_PACK, f))) {
-      edpack(&settings, oldhash, PACK_ENC);
-      len = fread(&settings.bots, 1, SIZE_CONF, f);
-      edpack(&settings, oldhash, PACK_DEC);
-    } else
-      return NULL;
-
-    char *p = oldhash;
-    OPENSSL_cleanse(oldhash, sizeof(settings.hash));
-    OPENSSL_cleanse(settings.hash, sizeof(settings.hash));
-    free(p);
-    fclose(f);
     return ".";
   }
 
@@ -129,10 +157,9 @@ bin_checksum(const char *fname, int todo)
         strlcpy(hash, btoh(md5out, MD5_DIGEST_LENGTH), sizeof(hash));
         OPENSSL_cleanse(&ctx, sizeof(ctx));
 
-        strlcpy(settings.hash, hash, 65);
+        strlcpy(settings.hash, hash, sizeof(settings.hash));
         edpack(&settings, hash, PACK_ENC);		/* encrypt the entire struct with the hash (including hash) */
         OPENSSL_cleanse(hash, sizeof(hash));
-
         if (todo & WRITE_PACK) {
           fwrite(&settings.hash, SIZE_PACK, 1, newbin->f);
           OPENSSL_cleanse(settings.hash, sizeof(settings.hash));
@@ -238,7 +265,7 @@ readcfg(const char *cfgfile)
 
   printf(STR("Reading '%s' "), cfgfile);
   while ((!feof(f)) && ((buffer = step_thru_file(f)) != NULL)) {
-    line++;
+    ++line;
     if ((*buffer)) {
       if (strchr(buffer, '\n'))
         *(char *) strchr(buffer, '\n') = 0;

+ 3 - 3
src/main.c

@@ -405,7 +405,7 @@ static void dtx_arg(int& argc, char *argv[])
         printf(STR("Revision: %d\n"), revision);
 	printf(STR("pack: %d conf: %d settings_t: %d prefix: %d pad: %d\n"), SIZE_PACK, SIZE_CONF, sizeof(settings_t), PREFIXLEN, SIZE_PAD);
         if (settings.uname[0]) {
-          sdebug++;
+          ++sdebug;
           bin_to_conf();
         }
 	exit(0);
@@ -438,7 +438,7 @@ void core_10secondly()
 #ifndef CYGWIN_HACKS
   static int curcheck = 0;
 
-  curcheck++;
+  ++curcheck;
 
   //FIXME: This is disabled because it sucks.
   if (curcheck == 1)
@@ -525,7 +525,7 @@ static void core_secondly()
     while (nowtm.tm_min != lastmin) {
       /* Timer drift, dammit */
       debug2("timer: drift (lastmin=%lu, now=%d)", lastmin, nowtm.tm_min);
-      i++;
+      ++i;
       lastmin = (lastmin + 1) % 60;
     }
     if (i > 1)