More IGE speedup.
[openssl.git] / apps / speed.c
index 75c34760f46bb475175cb853ce7236d4d81b1c31..c2ee1de6cc3cbf318933ee30c8481835219c9510 100644 (file)
 #ifndef OPENSSL_NO_AES
 #include <openssl/aes.h>
 #endif
+#ifndef OPENSSL_NO_CAMELLIA
+#include <openssl/camellia.h>
+#endif
 #ifndef OPENSSL_NO_MD2
 #include <openssl/md2.h>
 #endif
 #ifndef OPENSSL_NO_RIPEMD
 #include <openssl/ripemd.h>
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+#include <openssl/whrlpool.h>
+#endif
 #ifndef OPENSSL_NO_RC4
 #include <openssl/rc4.h>
 #endif
 #ifndef OPENSSL_NO_IDEA
 #include <openssl/idea.h>
 #endif
+#ifndef OPENSSL_NO_SEED
+#include <openssl/seed.h>
+#endif
 #ifndef OPENSSL_NO_BF
 #include <openssl/blowfish.h>
 #endif
 #define BUFSIZE        ((long)1024*8+1)
 int run=0;
 
-static char ftime_used = 0, times_used = 0, gettimeofday_used = 0, getrusage_used = 0;
 static int mr=0;
 static int usertime=1;
 
@@ -196,7 +204,7 @@ static void print_result(int alg,int run_no,int count,double time_used);
 static int do_multi(int multi);
 #endif
 
-#define ALGOR_NUM      21
+#define ALGOR_NUM      29
 #define SIZE_NUM       5
 #define RSA_NUM                4
 #define DSA_NUM                3
@@ -206,9 +214,12 @@ static int do_multi(int multi);
 
 static const char *names[ALGOR_NUM]={
   "md2","mdc2","md4","md5","hmac(md5)","sha1","rmd160","rc4",
-  "des cbc","des ede3","idea cbc",
+  "des cbc","des ede3","idea cbc","seed cbc",
   "rc2 cbc","rc5-32/12 cbc","blowfish cbc","cast cbc",
-  "aes-128 cbc","aes-192 cbc","aes-256 cbc","evp","sha256","sha512"};
+  "aes-128 cbc","aes-192 cbc","aes-256 cbc",
+  "camellia-128 cbc","camellia-192 cbc","camellia-256 cbc",
+  "evp","sha256","sha512","whirlpool",
+  "aes-128 ige","aes-192 ige","aes-256 ige"};
 static double results[ALGOR_NUM][SIZE_NUM];
 static int lengths[SIZE_NUM]={16,64,256,1024,8*1024};
 static double rsa_results[RSA_NUM][2];
@@ -345,6 +356,9 @@ int MAIN(int argc, char **argv)
        unsigned char sha512[SHA512_DIGEST_LENGTH];
 #endif
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+       unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
+#endif
 #ifndef OPENSSL_NO_RIPEMD
        unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
 #endif
@@ -360,6 +374,9 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_IDEA
        IDEA_KEY_SCHEDULE idea_ks;
 #endif
+#ifndef OPENSSL_NO_SEED
+       SEED_KEY_SCHEDULE seed_ks;
+#endif
 #ifndef OPENSSL_NO_BF
        BF_KEY bf_ks;
 #endif
@@ -380,6 +397,17 @@ int MAIN(int argc, char **argv)
                 0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,
                 0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56};
 #endif
+#ifndef OPENSSL_NO_CAMELLIA
+       static const unsigned char ckey24[24]=
+               {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+                0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+                0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+       static const unsigned char ckey32[32]=
+               {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,
+                0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,
+                0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,
+                0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56};
+#endif
 #ifndef OPENSSL_NO_AES
 #define MAX_BLOCK_SIZE 128
 #else
@@ -399,6 +427,9 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_AES
        AES_KEY aes_ks1, aes_ks2, aes_ks3;
 #endif
+#ifndef OPENSSL_NO_CAMELLIA
+       CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3;
+#endif
 #define        D_MD2           0
 #define        D_MDC2          1
 #define        D_MD4           2
@@ -410,16 +441,24 @@ int MAIN(int argc, char **argv)
 #define        D_CBC_DES       8
 #define        D_EDE3_DES      9
 #define        D_CBC_IDEA      10
-#define        D_CBC_RC2       11
-#define        D_CBC_RC5       12
-#define        D_CBC_BF        13
-#define        D_CBC_CAST      14
-#define D_CBC_128_AES  15
-#define D_CBC_192_AES  16
-#define D_CBC_256_AES  17
-#define D_EVP          18
-#define D_SHA256       19
-#define D_SHA512       20
+#define        D_CBC_SEED      11
+#define        D_CBC_RC2       12
+#define        D_CBC_RC5       13
+#define        D_CBC_BF        14
+#define        D_CBC_CAST      15
+#define D_CBC_128_AES  16
+#define D_CBC_192_AES  17
+#define D_CBC_256_AES  18
+#define D_CBC_128_CML   19 
+#define D_CBC_192_CML   20
+#define D_CBC_256_CML   21 
+#define D_EVP          22
+#define D_SHA256       23      
+#define D_SHA512       24
+#define D_WHIRLPOOL    25
+#define D_IGE_128_AES   26
+#define D_IGE_192_AES   27
+#define D_IGE_256_AES   28
        double d=0.0;
        long c[ALGOR_NUM][SIZE_NUM];
 #define        R_DSA_512       0
@@ -739,6 +778,10 @@ int MAIN(int argc, char **argv)
                else
 #endif
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+                       if (strcmp(*argv,"whirlpool") == 0) doit[D_WHIRLPOOL]=1;
+               else
+#endif
 #ifndef OPENSSL_NO_RIPEMD
                        if (strcmp(*argv,"ripemd") == 0) doit[D_RMD160]=1;
                else
@@ -760,6 +803,15 @@ int MAIN(int argc, char **argv)
                        if (strcmp(*argv,"aes-128-cbc") == 0) doit[D_CBC_128_AES]=1;
                else    if (strcmp(*argv,"aes-192-cbc") == 0) doit[D_CBC_192_AES]=1;
                else    if (strcmp(*argv,"aes-256-cbc") == 0) doit[D_CBC_256_AES]=1;
+               else    if (strcmp(*argv,"aes-128-ige") == 0) doit[D_IGE_128_AES]=1;
+               else    if (strcmp(*argv,"aes-192-ige") == 0) doit[D_IGE_192_AES]=1;
+               else    if (strcmp(*argv,"aes-256-ige") == 0) doit[D_IGE_256_AES]=1;
+                else
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+                       if (strcmp(*argv,"camellia-128-cbc") == 0) doit[D_CBC_128_CML]=1;
+               else    if (strcmp(*argv,"camellia-192-cbc") == 0) doit[D_CBC_192_CML]=1;
+               else    if (strcmp(*argv,"camellia-256-cbc") == 0) doit[D_CBC_256_CML]=1;
                else
 #endif
 #ifndef OPENSSL_NO_RSA
@@ -803,6 +855,11 @@ int MAIN(int argc, char **argv)
                else if (strcmp(*argv,"idea") == 0) doit[D_CBC_IDEA]=1;
                else
 #endif
+#ifndef OPENSSL_NO_SEED
+                    if (strcmp(*argv,"seed-cbc") == 0) doit[D_CBC_SEED]=1;
+               else if (strcmp(*argv,"seed") == 0) doit[D_CBC_SEED]=1;
+               else
+#endif
 #ifndef OPENSSL_NO_BF
                     if (strcmp(*argv,"bf-cbc") == 0) doit[D_CBC_BF]=1;
                else if (strcmp(*argv,"blowfish") == 0) doit[D_CBC_BF]=1;
@@ -832,6 +889,15 @@ int MAIN(int argc, char **argv)
                        }
                else
 #endif
+#ifndef OPENSSL_NO_CAMELLIA
+                       if (strcmp(*argv,"camellia") == 0)
+                       {
+                       doit[D_CBC_128_CML]=1;
+                       doit[D_CBC_192_CML]=1;
+                       doit[D_CBC_256_CML]=1;
+                       }
+               else
+#endif
 #ifndef OPENSSL_NO_RSA
                        if (strcmp(*argv,"rsa") == 0)
                        {
@@ -927,18 +993,25 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_SHA512
                        BIO_printf(bio_err,"sha512   ");
 #endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+                       BIO_printf(bio_err,"whirlpool");
+#endif
 #ifndef OPENSSL_NO_RIPEMD160
                        BIO_printf(bio_err,"rmd160");
 #endif
 #if !defined(OPENSSL_NO_MD2) || !defined(OPENSSL_NO_MDC2) || \
     !defined(OPENSSL_NO_MD4) || !defined(OPENSSL_NO_MD5) || \
-    !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160)
+    !defined(OPENSSL_NO_SHA1) || !defined(OPENSSL_NO_RIPEMD160) || \
+    !defined(OPENSSL_NO_WHIRLPOOL)
                        BIO_printf(bio_err,"\n");
 #endif
 
 #ifndef OPENSSL_NO_IDEA
                        BIO_printf(bio_err,"idea-cbc ");
 #endif
+#ifndef OPENSSL_NO_SEED
+                       BIO_printf(bio_err,"seed-cbc ");
+#endif
 #ifndef OPENSSL_NO_RC2
                        BIO_printf(bio_err,"rc2-cbc  ");
 #endif
@@ -948,7 +1021,7 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_BF
                        BIO_printf(bio_err,"bf-cbc");
 #endif
-#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_RC2) || \
+#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || !defined(OPENSSL_NO_RC2) || \
     !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_RC5)
                        BIO_printf(bio_err,"\n");
 #endif
@@ -957,6 +1030,11 @@ int MAIN(int argc, char **argv)
 #endif
 #ifndef OPENSSL_NO_AES
                        BIO_printf(bio_err,"aes-128-cbc aes-192-cbc aes-256-cbc ");
+                       BIO_printf(bio_err,"aes-128-ige aes-192-ige aes-256-ige ");
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+                       BIO_printf(bio_err,"\n");
+                       BIO_printf(bio_err,"camellia-128-cbc camellia-192-cbc camellia-256-cbc ");
 #endif
 #ifndef OPENSSL_NO_RC4
                        BIO_printf(bio_err,"rc4");
@@ -986,6 +1064,9 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_IDEA
                        BIO_printf(bio_err,"idea     ");
 #endif
+#ifndef OPENSSL_NO_SEED
+                       BIO_printf(bio_err,"seed     ");
+#endif
 #ifndef OPENSSL_NO_RC2
                        BIO_printf(bio_err,"rc2      ");
 #endif
@@ -995,15 +1076,19 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_AES
                        BIO_printf(bio_err,"aes      ");
 #endif
+#ifndef OPENSSL_NO_CAMELLIA
+                       BIO_printf(bio_err,"camellia ");
+#endif
 #ifndef OPENSSL_NO_RSA
                        BIO_printf(bio_err,"rsa      ");
 #endif
 #ifndef OPENSSL_NO_BF
                        BIO_printf(bio_err,"blowfish");
 #endif
-#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_RC2) || \
-    !defined(OPENSSL_NO_DES) || !defined(OPENSSL_NO_RSA) || \
-    !defined(OPENSSL_NO_BF) || !defined(OPENSSL_NO_AES)
+#if !defined(OPENSSL_NO_IDEA) || !defined(OPENSSL_NO_SEED) || \
+    !defined(OPENSSL_NO_RC2) || !defined(OPENSSL_NO_DES) || \
+    !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_BF) || \
+    !defined(OPENSSL_NO_AES) || !defined(OPENSSL_NO_CAMELLIA)
                        BIO_printf(bio_err,"\n");
 #endif
 
@@ -1050,11 +1135,6 @@ int MAIN(int argc, char **argv)
 
        if (usertime == 0 && !mr)
                BIO_printf(bio_err,"You have chosen to measure elapsed time instead of user CPU time.\n");
-       if (usertime <= 0 && !mr)
-               {
-               BIO_printf(bio_err,"To get the most accurate results, try to run this\n");
-               BIO_printf(bio_err,"program when this computer is idle.\n");
-               }
 
 #ifndef OPENSSL_NO_RSA
        for (i=0; i<RSA_NUM; i++)
@@ -1097,9 +1177,17 @@ int MAIN(int argc, char **argv)
        AES_set_encrypt_key(key24,192,&aes_ks2);
        AES_set_encrypt_key(key32,256,&aes_ks3);
 #endif
+#ifndef OPENSSL_NO_CAMELLIA
+       Camellia_set_key(key16,128,&camellia_ks1);
+       Camellia_set_key(ckey24,192,&camellia_ks2);
+       Camellia_set_key(ckey32,256,&camellia_ks3);
+#endif
 #ifndef OPENSSL_NO_IDEA
        idea_set_encrypt_key(key16,&idea_ks);
 #endif
+#ifndef OPENSSL_NO_SEED
+       SEED_set_key(key16,&seed_ks);
+#endif
 #ifndef OPENSSL_NO_RC4
        RC4_set_key(&rc4_ks,16,key16);
 #endif
@@ -1143,6 +1231,7 @@ int MAIN(int argc, char **argv)
        c[D_CBC_DES][0]=count;
        c[D_EDE3_DES][0]=count/3;
        c[D_CBC_IDEA][0]=count;
+       c[D_CBC_SEED][0]=count;
        c[D_CBC_RC2][0]=count;
        c[D_CBC_RC5][0]=count;
        c[D_CBC_BF][0]=count;
@@ -1150,8 +1239,15 @@ int MAIN(int argc, char **argv)
        c[D_CBC_128_AES][0]=count;
        c[D_CBC_192_AES][0]=count;
        c[D_CBC_256_AES][0]=count;
+       c[D_CBC_128_CML][0]=count;
+       c[D_CBC_192_CML][0]=count;
+       c[D_CBC_256_CML][0]=count;
        c[D_SHA256][0]=count;
        c[D_SHA512][0]=count;
+       c[D_WHIRLPOOL][0]=count;
+       c[D_IGE_128_AES][0]=count;
+       c[D_IGE_192_AES][0]=count;
+       c[D_IGE_256_AES][0]=count;
 
        for (i=1; i<SIZE_NUM; i++)
                {
@@ -1164,6 +1260,7 @@ int MAIN(int argc, char **argv)
                c[D_RMD160][i]=c[D_RMD160][0]*4*lengths[0]/lengths[i];
                c[D_SHA256][i]=c[D_SHA256][0]*4*lengths[0]/lengths[i];
                c[D_SHA512][i]=c[D_SHA512][0]*4*lengths[0]/lengths[i];
+               c[D_WHIRLPOOL][i]=c[D_WHIRLPOOL][0]*4*lengths[0]/lengths[i];
                }
        for (i=1; i<SIZE_NUM; i++)
                {
@@ -1175,6 +1272,7 @@ int MAIN(int argc, char **argv)
                c[D_CBC_DES][i]=c[D_CBC_DES][i-1]*l0/l1;
                c[D_EDE3_DES][i]=c[D_EDE3_DES][i-1]*l0/l1;
                c[D_CBC_IDEA][i]=c[D_CBC_IDEA][i-1]*l0/l1;
+               c[D_CBC_SEED][i]=c[D_CBC_SEED][i-1]*l0/l1;
                c[D_CBC_RC2][i]=c[D_CBC_RC2][i-1]*l0/l1;
                c[D_CBC_RC5][i]=c[D_CBC_RC5][i-1]*l0/l1;
                c[D_CBC_BF][i]=c[D_CBC_BF][i-1]*l0/l1;
@@ -1182,6 +1280,12 @@ int MAIN(int argc, char **argv)
                c[D_CBC_128_AES][i]=c[D_CBC_128_AES][i-1]*l0/l1;
                c[D_CBC_192_AES][i]=c[D_CBC_192_AES][i-1]*l0/l1;
                c[D_CBC_256_AES][i]=c[D_CBC_256_AES][i-1]*l0/l1;
+               c[D_CBC_128_CML][i]=c[D_CBC_128_CML][i-1]*l0/l1;
+               c[D_CBC_192_CML][i]=c[D_CBC_192_CML][i-1]*l0/l1;
+               c[D_CBC_256_CML][i]=c[D_CBC_256_CML][i-1]*l0/l1;
+               c[D_IGE_128_AES][i]=c[D_IGE_128_AES][i-1]*l0/l1;
+               c[D_IGE_192_AES][i]=c[D_IGE_192_AES][i-1]*l0/l1;
+               c[D_IGE_256_AES][i]=c[D_IGE_256_AES][i-1]*l0/l1;
                }
 #ifndef OPENSSL_NO_RSA
        rsa_c[R_RSA_512][0]=count/2000;
@@ -1472,8 +1576,23 @@ int MAIN(int argc, char **argv)
                        }
                }
 #endif
+#endif
 
+#ifndef OPENSSL_NO_WHIRLPOOL
+       if (doit[D_WHIRLPOOL])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_WHIRLPOOL],c[D_WHIRLPOOL][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_WHIRLPOOL][j]); count++)
+                               WHIRLPOOL(buf,lengths[j],whirlpool);
+                       d=Time_F(STOP);
+                       print_result(D_WHIRLPOOL,j,count,d);
+                       }
+               }
 #endif
+
 #ifndef OPENSSL_NO_RIPEMD
        if (doit[D_RMD160])
                {
@@ -1577,6 +1696,95 @@ int MAIN(int argc, char **argv)
                        }
                }
 
+       if (doit[D_IGE_128_AES])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_IGE_128_AES],c[D_IGE_128_AES][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_IGE_128_AES][j]); count++)
+                               AES_ige_encrypt(buf,buf2,
+                                       (unsigned long)lengths[j],&aes_ks1,
+                                       iv,AES_ENCRYPT);
+                       d=Time_F(STOP);
+                       print_result(D_IGE_128_AES,j,count,d);
+                       }
+               }
+       if (doit[D_IGE_192_AES])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_IGE_192_AES],c[D_IGE_192_AES][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_IGE_192_AES][j]); count++)
+                               AES_ige_encrypt(buf,buf2,
+                                       (unsigned long)lengths[j],&aes_ks2,
+                                       iv,AES_ENCRYPT);
+                       d=Time_F(STOP);
+                       print_result(D_IGE_192_AES,j,count,d);
+                       }
+               }
+       if (doit[D_IGE_256_AES])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_IGE_256_AES],c[D_IGE_256_AES][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_IGE_256_AES][j]); count++)
+                               AES_ige_encrypt(buf,buf2,
+                                       (unsigned long)lengths[j],&aes_ks3,
+                                       iv,AES_ENCRYPT);
+                       d=Time_F(STOP);
+                       print_result(D_IGE_256_AES,j,count,d);
+                       }
+               }
+
+
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+       if (doit[D_CBC_128_CML])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_CBC_128_CML],c[D_CBC_128_CML][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_CBC_128_CML][j]); count++)
+                               Camellia_cbc_encrypt(buf,buf,
+                                       (unsigned long)lengths[j],&camellia_ks1,
+                                       iv,CAMELLIA_ENCRYPT);
+                       d=Time_F(STOP);
+                       print_result(D_CBC_128_CML,j,count,d);
+                       }
+               }
+       if (doit[D_CBC_192_CML])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_CBC_192_CML],c[D_CBC_192_CML][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_CBC_192_CML][j]); count++)
+                               Camellia_cbc_encrypt(buf,buf,
+                                       (unsigned long)lengths[j],&camellia_ks2,
+                                       iv,CAMELLIA_ENCRYPT);
+                       d=Time_F(STOP);
+                       print_result(D_CBC_192_CML,j,count,d);
+                       }
+               }
+       if (doit[D_CBC_256_CML])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_CBC_256_CML],c[D_CBC_256_CML][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_CBC_256_CML][j]); count++)
+                               Camellia_cbc_encrypt(buf,buf,
+                                       (unsigned long)lengths[j],&camellia_ks3,
+                                       iv,CAMELLIA_ENCRYPT);
+                       d=Time_F(STOP);
+                       print_result(D_CBC_256_CML,j,count,d);
+                       }
+               }
+
 #endif
 #ifndef OPENSSL_NO_IDEA
        if (doit[D_CBC_IDEA])
@@ -1594,6 +1802,21 @@ int MAIN(int argc, char **argv)
                        }
                }
 #endif
+#ifndef OPENSSL_NO_SEED
+       if (doit[D_CBC_SEED])
+               {
+               for (j=0; j<SIZE_NUM; j++)
+                       {
+                       print_message(names[D_CBC_SEED],c[D_CBC_SEED][j],lengths[j]);
+                       Time_F(START);
+                       for (count=0,run=1; COND(c[D_CBC_SEED][j]); count++)
+                               SEED_cbc_encrypt(buf,buf,
+                                       (unsigned long)lengths[j],&seed_ks,iv,1);
+                       d=Time_F(STOP);
+                       print_result(D_CBC_SEED,j,count,d);
+                       }
+               }
+#endif
 #ifndef OPENSSL_NO_RC2
        if (doit[D_CBC_RC2])
                {
@@ -2383,6 +2606,7 @@ static int do_multi(int multi)
                        close(fd[1]);
                        mr=1;
                        usertime=0;
+                       free(fds);
                        return 0;
                        }
                printf("Forked child %d\n",n);
@@ -2531,7 +2755,10 @@ static int do_multi(int multi)
                        else
                                fprintf(stderr,"Unknown type '%s' from child %d\n",buf,n);
                        }
+
+               fclose(f);
                }
+       free(fds);
        return 1;
        }
 #endif