[hipl-commit] [trunk] Rev 3605: Uncrustify the i3 source files.

  • From: Mircea Gherzan <mircea.gherzan@xxxxxxxxxxxxxx>
  • To: hipl-commit@xxxxxxxxxxxxx
  • Date: Thu, 11 Feb 2010 13:50:10 +0200

Committer: Mircea Gherzan <mircea.gherzan@xxxxxxxxxxxxxx>
Date: Thu Feb 11 12:49:47 2010 +0100
Revision: 3605
Revision-id: mircea.gherzan@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Branch nick: trunk

Log:
  Uncrustify the i3 source files.

Modified:
  M  i3/aeshash/aes.h
  M  i3/aeshash/aescpp.h
  M  i3/aeshash/aescrypp.c
  M  i3/aeshash/aescrypt.c
  M  i3/aeshash/aeshash.c
  M  i3/aeshash/aeskey.c
  M  i3/aeshash/aeskeypp.c
  M  i3/aeshash/aesopt.h
  M  i3/aeshash/aestab.c
  M  i3/chord/api.c
  M  i3/chord/chord.c
  M  i3/chord/chord.h
  M  i3/chord/chord_api.h
  M  i3/chord/chord_getfingers.c
  M  i3/chord/chord_traceroute.c
  M  i3/chord/debug.h
  M  i3/chord/eprintf.c
  M  i3/chord/eprintf.h
  M  i3/chord/finger.c
  M  i3/chord/gen_conf.c
  M  i3/chord/gen_conf_same.c
  M  i3/chord/hosts.c
  M  i3/chord/join.c
  M  i3/chord/pack.c
  M  i3/chord/process.c
  M  i3/chord/sendpkt.c
  M  i3/chord/stabilize.c
  M  i3/chord/test.c
  M  i3/chord/util.c
  M  i3/i3/debug_fns.h
  M  i3/i3/i3.h
  M  i3/i3/i3_addr.c
  M  i3/i3/i3_addr.h
  M  i3/i3/i3_api.c
  M  i3/i3/i3_api.h
  M  i3/i3/i3_config.c
  M  i3/i3/i3_config.h
  M  i3/i3/i3_debug.c
  M  i3/i3/i3_debug.h
  M  i3/i3/i3_fun.h
  M  i3/i3/i3_header.c
  M  i3/i3/i3_header.h
  M  i3/i3/i3_id.c
  M  i3/i3/i3_id.h
  M  i3/i3/i3_misc.c
  M  i3/i3/i3_misc.h
  M  i3/i3/i3_options.c
  M  i3/i3/i3_options.h
  M  i3/i3/i3_ping.c
  M  i3/i3/i3_ping.h
  M  i3/i3/i3_stack.c
  M  i3/i3/i3_stack.h
  M  i3/i3/i3_tcp_fns.c
  M  i3/i3/i3_tcp_fns.h
  M  i3/i3/i3_trigger.c
  M  i3/i3/i3_trigger.h
  M  i3/i3/i3_utils.c
  M  i3/i3/i3_utils.h
  M  i3/i3/token_bucket.c
  M  i3/i3/token_bucket.h
  M  i3/i3_client/coordinates.c
  M  i3/i3_client/coordinates.h
  M  i3/i3_client/downhill_simplex.c
  M  i3/i3_client/downhill_simplex.h
  M  i3/i3_client/http.c
  M  i3/i3_client/http.h
  M  i3/i3_client/i3_client.h
  M  i3/i3_client/i3_client_api.c
  M  i3/i3_client/i3_client_api.h
  M  i3/i3_client/i3_client_api_ctx.c
  M  i3/i3_client/i3_client_api_ctx.h
  M  i3/i3_client/i3_client_api_ext.c
  M  i3/i3_client/i3_client_callback.c
  M  i3/i3_client/i3_client_callback.h
  M  i3/i3_client/i3_client_context.c
  M  i3/i3_client/i3_client_context.h
  M  i3/i3_client/i3_client_fd.c
  M  i3/i3_client/i3_client_fd.h
  M  i3/i3_client/i3_client_fun.h
  M  i3/i3_client/i3_client_id.c
  M  i3/i3_client/i3_client_id.h
  M  i3/i3_client/i3_client_params.h
  M  i3/i3_client/i3_client_pkt.c
  M  i3/i3_client/i3_client_pkt.h
  M  i3/i3_client/i3_client_timer.c
  M  i3/i3_client/i3_client_timer.h
  M  i3/i3_client/i3_client_trigger.c
  M  i3/i3_client/i3_client_trigger.h
  M  i3/i3_client/i3server_list.c
  M  i3/i3_client/i3server_list.h
  M  i3/i3_client/ping.c
  M  i3/i3_client/ping.h
  M  i3/i3_client/ping_thread.c
  M  i3/i3_client/ping_thread.h
  M  i3/i3_client/qsort.c
  M  i3/utils/byteorder.c
  M  i3/utils/byteorder.h
  M  i3/utils/eprintf.c
  M  i3/utils/eprintf.h
  M  i3/utils/event.c
  M  i3/utils/event.h
  M  i3/utils/fwint.h
  M  i3/utils/gen_utils.c
  M  i3/utils/gen_utils.h
  M  i3/utils/inetfns.c
  M  i3/utils/inetfns.h
  M  i3/utils/netwrap.h
  M  i3/utils/netwrap_posix.c
  M  i3/utils/netwrap_win32.c
  M  i3/utils/utils.h

=== modified file 'i3/aeshash/aes.h'
--- i3/aeshash/aes.h    2009-12-29 21:08:52 +0000
+++ i3/aeshash/aes.h    2010-02-11 11:49:47 +0000
@@ -1,110 +1,110 @@
-/*
- -------------------------------------------------------------------------
- Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary 
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright 
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products 
-      built using this software without specific written permission. 
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness 
- and fitness for purpose.
- -------------------------------------------------------------------------
- Issue Date: 29/07/2002
-
- This file contains the definitions required to use AES (Rijndael) in C.
-*/
-
-#ifndef _AES_H
-#define _AES_H
-
-
-#define __int64 long long
-
-/*  This include is used only to find 8 and 32 bit unsigned integer types   */
-
-#include <limits.h>
-
-#if UCHAR_MAX == 0xff       /* an unsigned 8 bit type for internal AES use  */
-  typedef unsigned char      aes_08t;
-#else
-#error Please define an unsigned 8 bit type in aes.h
-#endif
-
-#if UINT_MAX == 0xffffffff  /* an unsigned 32 bit type for internal AES use */
-  typedef   unsigned int     aes_32t;
-#elif ULONG_MAX == 0xffffffff
-  typedef   unsigned long    aes_32t;
-#else
-#error Please define an unsigned 32 bit type in aes.h
-#endif
-
-/*  BLOCK_SIZE is in BYTES: 16, 24, 32 or undefined for aes.c and 16, 20, 
-    24, 28, 32 or undefined for aespp.c.  When left undefined a slower 
-    version that provides variable block length is compiled.    
-*/
-
-#define BLOCK_SIZE 16 
-
-/* key schedule length (in 32-bit words)    */
-
-#if !defined(BLOCK_SIZE)
-#define KS_LENGTH   128
-#else
-#define KS_LENGTH   4 * BLOCK_SIZE
-#endif
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-typedef unsigned int aes_fret;   /* type for function return value       */
-#define aes_bad      0           /* bad function return value            */
-#define aes_good     1           /* good function return value           */
-#ifndef AES_DLL                  /* implement normal or DLL functions    */
-#define aes_rval     aes_fret
-#else
-#define aes_rval     aes_fret __declspec(dllexport) _stdcall
-#endif
-
-
-typedef struct                     /* the AES context for encryption   */
-{   aes_32t    k_sch[KS_LENGTH];   /* the encryption key schedule      */
-    aes_32t    n_rnd;              /* the number of cipher rounds      */
-    aes_32t    n_blk;              /* the number of bytes in the state */
-} aes_ctx;
-
-#if !defined(BLOCK_SIZE)
-aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
-#endif
-
-aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1]);
-aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1]);
-
-aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1]);
-aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1]);
-
-void aeshash_l(const unsigned char in[], unsigned char out[]);
-void aeshash_r(const unsigned char in[], unsigned char out[]);
-void aeshash_init(void);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ *    notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ *    built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ * -------------------------------------------------------------------------
+ * Issue Date: 29/07/2002
+ *
+ * This file contains the definitions required to use AES (Rijndael) in C.
+ */
+
+#ifndef _AES_H
+#define _AES_H
+
+
+#define __int64 long long
+
+/*  This include is used only to find 8 and 32 bit unsigned integer types   */
+
+#include <limits.h>
+
+#if UCHAR_MAX == 0xff       /* an unsigned 8 bit type for internal AES use  */
+typedef unsigned char aes_08t;
+#else
+#error Please define an unsigned 8 bit type in aes.h
+#endif
+
+#if UINT_MAX == 0xffffffff  /* an unsigned 32 bit type for internal AES use */
+typedef   unsigned int aes_32t;
+#elif ULONG_MAX == 0xffffffff
+typedef   unsigned long aes_32t;
+#else
+#error Please define an unsigned 32 bit type in aes.h
+#endif
+
+/*  BLOCK_SIZE is in BYTES: 16, 24, 32 or undefined for aes.c and 16, 20,
+ *  24, 28, 32 or undefined for aespp.c.  When left undefined a slower
+ *  version that provides variable block length is compiled.
+ */
+
+#define BLOCK_SIZE 16
+
+/* key schedule length (in 32-bit words)    */
+
+#if !defined(BLOCK_SIZE)
+#define KS_LENGTH   128
+#else
+#define KS_LENGTH   4 * BLOCK_SIZE
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef unsigned int aes_fret;   /* type for function return value       */
+#define aes_bad      0           /* bad function return value            */
+#define aes_good     1           /* good function return value           */
+#ifndef AES_DLL                  /* implement normal or DLL functions    */
+#define aes_rval     aes_fret
+#else
+#define aes_rval     aes_fret __declspec(dllexport) _stdcall
+#endif
+
+
+typedef struct                     /* the AES context for encryption   */
+{ aes_32t k_sch[KS_LENGTH];        /* the encryption key schedule      */
+  aes_32t n_rnd;                   /* the number of cipher rounds      */
+  aes_32t n_blk;                   /* the number of bytes in the state */
+} aes_ctx;
+
+#if !defined(BLOCK_SIZE)
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
+#endif
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1]);
+aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1]);
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1]);
+aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1]);
+
+void aeshash_l(const unsigned char in[], unsigned char out[]);
+void aeshash_r(const unsigned char in[], unsigned char out[]);
+void aeshash_init(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif

=== modified file 'i3/aeshash/aescpp.h'
--- i3/aeshash/aescpp.h 2009-12-11 22:49:11 +0000
+++ i3/aeshash/aescpp.h 2010-02-11 11:49:47 +0000
@@ -1,54 +1,79 @@
-/*
- -------------------------------------------------------------------------
- Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxxx>, Worcester, UK.
- All rights reserved.
-
- TERMS
-
- Redistribution and use in source and binary forms, with or without 
- modification, are permitted subject to the following conditions:
-
-  1. Redistributions of source code must retain the above copyright 
-     notice, this list of conditions and the following disclaimer. 
-
-  2. Redistributions in binary form must reproduce the above copyright
-     notice, this list of conditions and the following disclaimer in the 
-     documentation and/or other materials provided with the distribution. 
-
-  3. The copyright holder's name must not be used to endorse or promote 
-     any products derived from this software without his specific prior 
-     written permission. 
-
- This software is provided 'as is' with no express or implied warranties 
- of correctness or fitness for purpose.
- -------------------------------------------------------------------------
- Issue Date: 21/01/2002
-
- This file contains the definitions required to use AES (Rijndael) in C++.
-*/
-
-#ifndef _AESCPP_H
-#define _AESCPP_H
-
-#include "aes.h"
-
-class AESclass
-{   aes_ctx cx[1];
-public:
-#if defined(BLOCK_SIZE)
-    AESclass()                          { cx->n_blk = BLOCK_SIZE; cx->n_rnd = 
0; }
-#else
-    AESclass(unsigned int blen = 16)    { cx->n_blk = blen; cx->n_rnd = 0; }
-    aes_rval blk_len(unsigned int blen) { return aes_blk_len(blen, cx); }
-#endif
-    aes_rval enc_key(const unsigned char in_key[], unsigned int klen)
-            { return aes_enc_key(in_key, klen, cx); }
-    aes_rval dec_key(const unsigned char in_key[], unsigned int klen)
-            { return aes_dec_key(in_key, klen, cx); }
-    aes_rval enc_blk(const unsigned char in_blk[], unsigned char out_blk[])
-            { return aes_enc_blk(in_blk, out_blk, cx); }
-    aes_rval dec_blk(const unsigned char in_blk[], unsigned char out_blk[])
-            { return aes_dec_blk(in_blk, out_blk, cx); }
-};
-
-#endif
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxxx>, Worcester, UK.
+ * All rights reserved.
+ *
+ * TERMS
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted subject to the following conditions:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * 3. The copyright holder's name must not be used to endorse or promote
+ *   any products derived from this software without his specific prior
+ *   written permission.
+ *
+ * This software is provided 'as is' with no express or implied warranties
+ * of correctness or fitness for purpose.
+ * -------------------------------------------------------------------------
+ * Issue Date: 21/01/2002
+ *
+ * This file contains the definitions required to use AES (Rijndael) in C++.
+ */
+
+#ifndef _AESCPP_H
+#define _AESCPP_H
+
+#include "aes.h"
+
+class AESclass
+{   aes_ctx cx[1];
+public:
+#if defined(BLOCK_SIZE)
+    AESclass()
+    {
+        cx->n_blk = BLOCK_SIZE;
+        cx->n_rnd = 0;
+    }
+
+#else
+    AESclass(unsigned int blen = 16)
+    {
+        cx->n_blk = blen;
+        cx->n_rnd = 0;
+    }
+
+    aes_rval blk_len(unsigned int blen)
+    {
+        return aes_blk_len(blen, cx);
+    }
+
+#endif
+    aes_rval enc_key(const unsigned char in_key[], unsigned int klen)
+    {
+        return aes_enc_key(in_key, klen, cx);
+    }
+
+    aes_rval dec_key(const unsigned char in_key[], unsigned int klen)
+    {
+        return aes_dec_key(in_key, klen, cx);
+    }
+
+    aes_rval enc_blk(const unsigned char in_blk[], unsigned char out_blk[])
+    {
+        return aes_enc_blk(in_blk, out_blk, cx);
+    }
+
+    aes_rval dec_blk(const unsigned char in_blk[], unsigned char out_blk[])
+    {
+        return aes_dec_blk(in_blk, out_blk, cx);
+    }
+};
+
+#endif

=== modified file 'i3/aeshash/aescrypp.c'
--- i3/aeshash/aescrypp.c       2009-12-11 22:49:11 +0000
+++ i3/aeshash/aescrypp.c       2010-02-11 11:49:47 +0000
@@ -1,487 +1,481 @@
-/*
- -------------------------------------------------------------------------
- Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary 
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright 
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products 
-      built using this software without specific written permission. 
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness 
- and fitness for purpose.
- -------------------------------------------------------------------------
- Issue Date: 29/07/2002
-
- This file contains the code for implementing encryption and decryption
- for AES (Rijndael) for block and key sizes of 16, 20, 24, 28 and 32 bytes.
- It can optionally be replaced by code written in assembler using NASM.
-*/
-
-#include "aesopt.h"
-
-#define unused  77  /* Sunset Strip */
-
-#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
-#define so(y,x,c)   word_out(y + 4 * c, s(x,c))
-
-#if BLOCK_SIZE == 16
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[4],y[4]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
- /* 
-   the following defines prevent the compiler requiring the declaration
-   of generated but unused variables in the fwd_var and inv_var macros
- */
-#define b04 unused
-#define b05 unused
-#define b06 unused
-#define b07 unused
-#define b14 unused
-#define b15 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-
-#elif BLOCK_SIZE == 20
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[5],y[5]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,y##0,y##1,y##2,y##3,y##4
-#define b05 unused
-#define b06 unused
-#define b07 unused
-#define b15 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); s(y,4) = s(x,4); 
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); 
si(y,x,k,4)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2);
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); 
rm(y,x,k,4)
-
-#elif BLOCK_SIZE == 24
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[6],y[6]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5, \
-                        y##0,y##1,y##2,y##3,y##4,y##5
-#define b06 unused
-#define b07 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
-                        si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); \
-                        so(y,x,3); so(y,x,4); so(y,x,5)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
-                        rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
-
-#elif BLOCK_SIZE == 28
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[7],y[7]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5,x##6 \
-                        y##0,y##1,y##2,y##3,y##4,y##5,y##6
-#define b07 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5);; s(y,6) = s(x,6);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
-                        si(y,x,k,3); si(y,x,k,4); si(y,x,k,5); si(y,x,k,6)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); \
-                        so(y,x,3); so(y,x,4); so(y,x,5); so(y,x,6)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
-                        rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6)
-#else
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[8],y[8]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
-                        y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5); \
-                        s(y,6) = s(x,6); s(y,7) = s(x,7);
-
-#if BLOCK_SIZE == 32
-
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
-                        si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
-                        so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
-                        rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
-#else
-
-#define state_in(y,x,k) \
-switch(nc) \
-{   case 8: si(y,x,k,7); \
-    case 7: si(y,x,k,6); \
-    case 6: si(y,x,k,5); \
-    case 5: si(y,x,k,4); \
-    case 4: si(y,x,k,3); si(y,x,k,2); \
-            si(y,x,k,1); si(y,x,k,0); \
-}
-
-#define state_out(y,x) \
-switch(nc) \
-{   case 8: so(y,x,7); \
-    case 7: so(y,x,6); \
-    case 6: so(y,x,5); \
-    case 5: so(y,x,4); \
-    case 4: so(y,x,3); so(y,x,2); \
-            so(y,x,1); so(y,x,0); \
-}
-
-#if defined(FAST_VARIABLE)
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{   case 8: rm(y,x,k,7); rm(y,x,k,6); \
-            rm(y,x,k,5); rm(y,x,k,4); \
-            rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-    case 7: rm(y,x,k,6); rm(y,x,k,5); \
-            rm(y,x,k,4); rm(y,x,k,3); \
-            rm(y,x,k,2); rm(y,x,k,1); \
-            rm(y,x,k,0); \
-            break; \
-    case 6: rm(y,x,k,5); rm(y,x,k,4); \
-            rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-    case 5: rm(y,x,k,4); rm(y,x,k,3); \
-            rm(y,x,k,2); rm(y,x,k,1); \
-            rm(y,x,k,0); \
-            break; \
-    case 4: rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-}
-#else
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{   case 8: rm(y,x,k,7); \
-    case 7: rm(y,x,k,6); \
-    case 6: rm(y,x,k,5); \
-    case 5: rm(y,x,k,4); \
-    case 4: rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-}
-
-#endif
-
-#endif
-#endif
-
-#if defined(ENCRYPTION)
-
-/* I am grateful to Frank Yellin for the following construction
-   (and that for decryption) which, given the column (c) of the 
-   output state variable, gives the input state variables which 
-   are needed for each row (r) of the state.
-
-   For the fixed block size options, compilers should reduce these 
-   two expressions to fixed variable references. But for variable 
-   block size code conditional clauses will sometimes be returned.
-
-   y = output word, x = input word, r = row, c = column for r = 0, 
-   1, 2 and 3 = column accessed for row r.
-*/
-
-#define fwd_var(x,r,c)\
- ( r == 0 ?           \
-    ( c == 0 ? s(x,0) \
-    : c == 1 ? s(x,1) \
-    : c == 2 ? s(x,2) \
-    : c == 3 ? s(x,3) \
-    : c == 4 ? s(x,4) \
-    : c == 5 ? s(x,5) \
-    : c == 6 ? s(x,6) \
-    :          s(x,7))\
- : r == 1 ?           \
-    ( c == 0 ? s(x,1) \
-    : c == 1 ? s(x,2) \
-    : c == 2 ? s(x,3) \
-    : c == 3 ? nc == 4 ? s(x,0) : s(x,4) \
-    : c == 4 ? nc == 5 ? s(x,0) : s(x,5) \
-    : c == 5 ? nc == 6 ? s(x,0) : s(x,6) \
-    : c == 6 ? nc == 7 ? s(x,0) : s(x,7) \
-    :          s(x,0))\
- : r == 2 ?           \
-    ( c == 0 ? nc == 8 ? s(x,3) : s(x,2) \
-    : c == 1 ? nc == 8 ? s(x,4) : s(x,3) \
-    : c == 2 ? nc == 8 ? s(x,5) : nc == 4 ? s(x,0) : s(x,4) \
-    : c == 3 ? nc == 8 ? s(x,6) : nc == 5 ? s(x,0) : nc == 4 ? s(x,1) : s(x,5) 
\
-    : c == 4 ? nc == 8 ? s(x,7) : nc == 7 ? s(x,6) : nc == 6 ? s(x,0) : s(x,1) 
\
-    : c == 5 ? nc == 6 ? s(x,1) : s(x,0) \
-    : c == 6 ? s(x,1) \
-    :          s(x,2))\
- :                    \
-    ( c == 0 ? nc >  6 ? s(x,4) : s(x,3) \
-    : c == 1 ? nc >  6 ? s(x,5) : nc == 4 ? s(x,0) : s(x,4) \
-    : c == 2 ? nc >  6 ? s(x,6) : nc == 6 ? s(x,5) : nc == 5 ? s(x,0) : s(x,1) 
\
-    : c == 3 ? nc == 8 ? s(x,7) : nc == 5 ? s(x,1) : nc == 4 ? s(x,2) : s(x,0) 
\
-    : c == 4 ? nc == 8 ? s(x,0) : nc == 5 ? s(x,2) : s(x,1) \
-    : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
-    : c == 6 ? nc == 8 ? s(x,2) : s(x,3) \
-    :          s(x,3)))
-
-#if defined(FT4_SET)
-#undef  dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ 
four_tables(x,ft_tab,fwd_var,rf1,c)
-#elif defined(FT1_SET)
-#undef  dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ 
one_table(x,upr,ft_tab,fwd_var,rf1,c)
-#else
-#define fwd_rnd(y,x,k,c)    s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) 
^ (k)[c]
-#endif
-
-#if defined(FL4_SET)
-#define fwd_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ 
four_tables(x,fl_tab,fwd_var,rf1,c)
-#elif defined(FL1_SET)
-#define fwd_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ 
one_table(x,ups,fl_tab,fwd_var,rf1,c)
-#else
-#define fwd_lrnd(y,x,k,c)   s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
-#endif
-
-aes_rval aes_enc_blk_(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1])
-{   aes_32t        locals(b0, b1);
-    const aes_32t  *kp = cx->k_sch;
-    dec_fmvars  /* declare variables for fwd_mcol() if needed */
-
-    if(!(cx->n_blk & 1)) return aes_bad;
-
-#if (ENC_UNROLL == FULL)
-
-    state_in((cx->n_rnd & 1 ? b1 : b0), in_blk, kp); 
-    kp += (cx->n_rnd - 9) * nc;
-
-    switch(cx->n_rnd)
-    {
-    case 14:    round(fwd_rnd,  b1, b0, kp - 4 * nc);
-    case 13:    round(fwd_rnd,  b0, b1, kp - 3 * nc);
-    case 12:    round(fwd_rnd,  b1, b0, kp - 2 * nc);
-    case 11:    round(fwd_rnd,  b0, b1, kp -     nc);
-    case 10:    round(fwd_rnd,  b1, b0, kp         );             
-                round(fwd_rnd,  b0, b1, kp +     nc);
-                round(fwd_rnd,  b1, b0, kp + 2 * nc); 
-                round(fwd_rnd,  b0, b1, kp + 3 * nc);
-                round(fwd_rnd,  b1, b0, kp + 4 * nc); 
-                round(fwd_rnd,  b0, b1, kp + 5 * nc);
-                round(fwd_rnd,  b1, b0, kp + 6 * nc); 
-                round(fwd_rnd,  b0, b1, kp + 7 * nc);
-                round(fwd_rnd,  b1, b0, kp + 8 * nc);
-                round(fwd_lrnd, b0, b1, kp + 9 * nc);
-    }
-#else
-    {   aes_32t    rnd;
-
-        state_in(b0, in_blk, kp); 
-
-#if (ENC_UNROLL == PARTIAL)
-
-        for(rnd = 0; rnd < (cx->n_rnd - 1) >> 1; ++rnd)
-        {
-            kp += nc;
-            round(fwd_rnd, b1, b0, kp); 
-            kp += nc;
-            round(fwd_rnd, b0, b1, kp); 
-        }
-
-        if(cx->n_rnd & 1) 
-        {
-            l_copy(b1, b0);
-        }
-        else
-        {
-            kp += nc;
-            round(fwd_rnd,  b1, b0, kp); 
-        }
-#else
-        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
-        {
-            kp += nc;
-            round(fwd_rnd, b1, b0, kp); 
-            l_copy(b0, b1); 
-        }
-#endif
-        kp += nc;
-        round(fwd_lrnd, b0, b1, kp);
-    }
-#endif
-
-    state_out(out_blk, b0);
-    return aes_good;
-}
-
-#endif
-
-#if defined(DECRYPTION)
-
-#define inv_var(x,r,c)\
- ( r == 0 ?           \
-    ( c == 0 ? s(x,0) \
-    : c == 1 ? s(x,1) \
-    : c == 2 ? s(x,2) \
-    : c == 3 ? s(x,3) \
-    : c == 4 ? s(x,4) \
-    : c == 5 ? s(x,5) \
-    : c == 6 ? s(x,6) \
-    :          s(x,7))\
- : r == 1 ?           \
-    ( c == 0 ? nc == 8 ? s(x,7) : nc == 7 ? s(x,6) : nc == 6 ? s(x,5) : nc == 
5 ? s(x,4) : s(x,3) \
-    : c == 1 ? s(x,0) \
-    : c == 2 ? s(x,1) \
-    : c == 3 ? s(x,2) \
-    : c == 4 ? s(x,3) \
-    : c == 5 ? s(x,4) \
-    : c == 6 ? s(x,5) \
-    :          s(x,6))\
- : r == 2 ?           \
-    ( c == 0 ? nc >  6 ? s(x,5) : nc == 6 ? s(x,4) : nc == 5 ? s(x,3) : s(x,2) 
\
-    : c == 1 ? nc >  6 ? s(x,6) : nc == 6 ? s(x,5) : nc == 5 ? s(x,4) : s(x,3) 
\
-    : c == 2 ? nc == 8 ? s(x,7) : s(x,0) \
-    : c == 3 ? nc == 8 ? s(x,0) : s(x,1) \
-    : c == 4 ? nc == 8 ? s(x,1) : s(x,2) \
-    : c == 5 ? nc == 8 ? s(x,2) : s(x,3) \
-    : c == 6 ? nc == 8 ? s(x,3) : s(x,4) \
-    :          s(x,4))\
- :                    \
-    ( c == 0 ? nc == 8 ? s(x,4) : nc == 5 ? s(x,2) : nc == 4 ? s(x,1) : s(x,3) 
\
-    : c == 1 ? nc == 8 ? s(x,5) : nc == 5 ? s(x,3) : nc == 4 ? s(x,2) : s(x,4) 
\
-    : c == 2 ? nc == 8 ? s(x,6) : nc == 5 ? s(x,4) : nc == 4 ? s(x,3) : s(x,5) 
\
-    : c == 3 ? nc == 8 ? s(x,7) : nc == 7 ? s(x,6) : s(x,0) \
-    : c == 4 ? nc >  6 ? s(x,0) : s(x,1) \
-    : c == 5 ? nc == 6 ? s(x,2) : s(x,1) \
-    : c == 6 ? s(x,2) \
-    :          s(x,3)))
-
-#if defined(IT4_SET)
-#undef  dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ 
four_tables(x,it_tab,inv_var,rf1,c)
-#elif defined(IT1_SET)
-#undef  dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ 
one_table(x,upr,it_tab,inv_var,rf1,c)
-#else
-#define inv_rnd(y,x,k,c)    s(y,c) = 
inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
-#endif
-
-#if defined(IL4_SET)
-#define inv_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ 
four_tables(x,il_tab,inv_var,rf1,c)
-#elif defined(IL1_SET)
-#define inv_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ 
one_table(x,ups,il_tab,inv_var,rf1,c)
-#else
-#define inv_lrnd(y,x,k,c)   s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ 
(k)[c]
-#endif
-
-aes_rval aes_dec_blk_(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1])
-{   aes_32t        locals(b0, b1);
-    const aes_32t  *kp = cx->k_sch + nc * cx->n_rnd;
-    dec_imvars  /* declare variables for inv_mcol() if needed */
-
-    if(!(cx->n_blk & 2)) return aes_bad;
-
-#if (DEC_UNROLL == FULL)
-
-    state_in((cx->n_rnd & 1 ? b1 : b0), in_blk, kp); 
-    kp = cx->k_sch + 9 * nc;
-
-    switch(cx->n_rnd)
-    {
-    case 14:    round(inv_rnd,  b1, b0, kp + 4 * nc);
-    case 13:    round(inv_rnd,  b0, b1, kp + 3 * nc);
-    case 12:    round(inv_rnd,  b1, b0, kp + 2 * nc);
-    case 11:    round(inv_rnd,  b0, b1, kp +     nc);
-    case 10:    round(inv_rnd,  b1, b0, kp         );             
-                round(inv_rnd,  b0, b1, kp -     nc);
-                round(inv_rnd,  b1, b0, kp - 2 * nc); 
-                round(inv_rnd,  b0, b1, kp - 3 * nc);
-                round(inv_rnd,  b1, b0, kp - 4 * nc); 
-                round(inv_rnd,  b0, b1, kp - 5 * nc);
-                round(inv_rnd,  b1, b0, kp - 6 * nc); 
-                round(inv_rnd,  b0, b1, kp - 7 * nc);
-                round(inv_rnd,  b1, b0, kp - 8 * nc);
-                round(inv_lrnd, b0, b1, kp - 9 * nc);
-    }
-#else
-    {   aes_32t    rnd;
-
-        state_in(b0, in_blk, kp); 
-
-#if (DEC_UNROLL == PARTIAL)
-
-        for(rnd = 0; rnd < (cx->n_rnd - 1) >> 1; ++rnd)
-        {
-            kp -= nc;
-            round(inv_rnd, b1, b0, kp); 
-            kp -= nc;
-            round(inv_rnd, b0, b1, kp); 
-        }
-
-        if(cx->n_rnd & 1) 
-        {
-            l_copy(b1, b0);
-        }
-        else
-        {       
-            kp -= nc;
-            round(inv_rnd,  b1, b0, kp); 
-        }
-#else
-        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
-        {
-            kp -= nc;
-            round(inv_rnd, b1, b0, kp); 
-            l_copy(b0, b1); 
-        }
-#endif
-        kp -= nc;
-        round(inv_lrnd, b0, b1, kp);
-    }
-#endif
-
-    state_out(out_blk, b0);
-    return aes_good;
-}
-
-#endif
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ *    notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ *    built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ * -------------------------------------------------------------------------
+ * Issue Date: 29/07/2002
+ *
+ * This file contains the code for implementing encryption and decryption
+ * for AES (Rijndael) for block and key sizes of 16, 20, 24, 28 and 32 bytes.
+ * It can optionally be replaced by code written in assembler using NASM.
+ */
+
+#include "aesopt.h"
+
+#define unused  77  /* Sunset Strip */
+
+#define si(y, x, k, c) s(y, c) = word_in(x + 4 * c) ^ k[c]
+#define so(y, x, c)   word_out(y + 4 * c, s(x, c))
+
+#if BLOCK_SIZE == 16
+
+#if defined(ARRAYS)
+#define locals(y, x)     x[4], y[4]
+#else
+#define locals(y, x)     x ## 0, x ## 1, x ## 2, x ## 3, y ## 0, y ## 1, y ## 
2, y ## 3
+/*
+ * the following defines prevent the compiler requiring the declaration
+ * of generated but unused variables in the fwd_var and inv_var macros
+ */
+#define b04 unused
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b14 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x)    s(y, 0) = s(x, 0); s(y, 1) = s(x, 1); \
+    s(y, 2)                     = s(x, 2); s(y, 3) = s(x, 3);
+#define state_in(y, x, k) si(y, x, k, 0); si(y, x, k, 1); si(y, x, k, 2); 
si(y, x, k, 3)
+#define state_out(y, x)  so(y, x, 0); so(y, x, 1); so(y, x, 2); so(y, x, 3)
+#define round(rm, y, x, k) rm(y, x, k, 0); rm(y, x, k, 1); rm(y, x, k, 2); 
rm(y, x, k, 3)
+
+#elif BLOCK_SIZE == 20
+
+#if defined(ARRAYS)
+#define locals(y, x)     x[5], y[5]
+#else
+#define locals(y, x)     x ## 0, x ## 1, x ## 2, x ## 3, x ## 4, y ## 0, y ## 
1, y ## 2, y ## 3, y ## 4
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x)    s(y, 0) = s(x, 0); s(y, 1) = s(x, 1); \
+    s(y, 2)                     = s(x, 2); s(y, 3) = s(x, 3); s(y, 4) = s(x, 
4);
+#define state_in(y, x, k) si(y, x, k, 0); si(y, x, k, 1); si(y, x, k, 2); 
si(y, x, k, 3); si(y, x, k, 4)
+#define state_out(y, x)  so(y, x, 0); so(y, x, 1); so(y, x, 2);
+#define round(rm, y, x, k) rm(y, x, k, 0); rm(y, x, k, 1); rm(y, x, k, 2); 
rm(y, x, k, 3); rm(y, x, k, 4)
+
+#elif BLOCK_SIZE == 24
+
+#if defined(ARRAYS)
+#define locals(y, x)     x[6], y[6]
+#else
+#define locals(y, x)     x ## 0, x ## 1, x ## 2, x ## 3, x ## 4, x ## 5, \
+    y ## 0, y ## 1, y ## 2, y ## 3, y ## 4, y ## 5
+#define b06 unused
+#define b07 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x)    s(y, 0) = s(x, 0); s(y, 1) = s(x, 1); \
+    s(y, 2)                     = s(x, 2); s(y, 3) = s(x, 3); \
+    s(y, 4)                     = s(x, 4); s(y, 5) = s(x, 5);
+#define state_in(y, x, k) si(y, x, k, 0); si(y, x, k, 1); si(y, x, k, 2); \
+    si(y, x, k, 3); si(y, x, k, 4); si(y, x, k, 5)
+#define state_out(y, x)  so(y, x, 0); so(y, x, 1); so(y, x, 2); \
+    so(y, x, 3); so(y, x, 4); so(y, x, 5)
+#define round(rm, y, x, k) rm(y, x, k, 0); rm(y, x, k, 1); rm(y, x, k, 2); \
+    rm(y, x, k, 3); rm(y, x, k, 4); rm(y, x, k, 5)
+
+#elif BLOCK_SIZE == 28
+
+#if defined(ARRAYS)
+#define locals(y, x)     x[7], y[7]
+#else
+#define locals(y, x)     x ## 0, x ## 1, x ## 2, x ## 3, x ## 4, x ## 5, x ## 
6 \
+    y ## 0, y ## 1, y ## 2, y ## 3, y ## 4, y ## 5, y ## 6
+#define b07 unused
+#define b17 unused
+#endif
+#define l_copy(y, x)    s(y, 0) = s(x, 0); s(y, 1) = s(x, 1); \
+    s(y, 2)                     = s(x, 2); s(y, 3) = s(x, 3); \
+    s(y, 4)                     = s(x, 4); s(y, 5) = s(x, 5);; s(y, 6) = s(x, 
6);
+#define state_in(y, x, k) si(y, x, k, 0); si(y, x, k, 1); si(y, x, k, 2); \
+    si(y, x, k, 3); si(y, x, k, 4); si(y, x, k, 5); si(y, x, k, 6)
+#define state_out(y, x)  so(y, x, 0); so(y, x, 1); so(y, x, 2); \
+    so(y, x, 3); so(y, x, 4); so(y, x, 5); so(y, x, 6)
+#define round(rm, y, x, k) rm(y, x, k, 0); rm(y, x, k, 1); rm(y, x, k, 2); \
+    rm(y, x, k, 3); rm(y, x, k, 4); rm(y, x, k, 5); rm(y, x, k, 6)
+#else
+
+#if defined(ARRAYS)
+#define locals(y, x)     x[8], y[8]
+#else
+#define locals(y, x)     x ## 0, x ## 1, x ## 2, x ## 3, x ## 4, x ## 5, x ## 
6, x ## 7, \
+    y ## 0, y ## 1, y ## 2, y ## 3, y ## 4, y ## 5, y ## 6, y ## 7
+#endif
+#define l_copy(y, x)    s(y, 0) = s(x, 0); s(y, 1) = s(x, 1); \
+    s(y, 2)                     = s(x, 2); s(y, 3) = s(x, 3); \
+    s(y, 4)                     = s(x, 4); s(y, 5) = s(x, 5); \
+    s(y, 6)                     = s(x, 6); s(y, 7) = s(x, 7);
+
+#if BLOCK_SIZE == 32
+
+#define state_in(y, x, k) si(y, x, k, 0); si(y, x, k, 1); si(y, x, k, 2); 
si(y, x, k, 3); \
+    si(y, x, k, 4); si(y, x, k, 5); si(y, x, k, 6); si(y, x, k, 7)
+#define state_out(y, x)  so(y, x, 0); so(y, x, 1); so(y, x, 2); so(y, x, 3); \
+    so(y, x, 4); so(y, x, 5); so(y, x, 6); so(y, x, 7)
+#define round(rm, y, x, k) rm(y, x, k, 0); rm(y, x, k, 1); rm(y, x, k, 2); 
rm(y, x, k, 3); \
+    rm(y, x, k, 4); rm(y, x, k, 5); rm(y, x, k, 6); rm(y, x, k, 7)
+#else
+
+#define state_in(y, x, k) \
+    switch (nc) \
+    {   case 8: si(y, x, k, 7); \
+    case 7: si(y, x, k, 6); \
+    case 6: si(y, x, k, 5); \
+    case 5: si(y, x, k, 4); \
+    case 4: si(y, x, k, 3); si(y, x, k, 2); \
+        si(y, x, k, 1); si(y, x, k, 0); \
+    }
+
+#define state_out(y, x) \
+    switch (nc) \
+    {   case 8: so(y, x, 7); \
+    case 7: so(y, x, 6); \
+    case 6: so(y, x, 5); \
+    case 5: so(y, x, 4); \
+    case 4: so(y, x, 3); so(y, x, 2); \
+        so(y, x, 1); so(y, x, 0); \
+    }
+
+#if defined(FAST_VARIABLE)
+
+#define round(rm, y, x, k) \
+    switch (nc) \
+    {   case 8: rm(y, x, k, 7); rm(y, x, k, 6); \
+        rm(y, x, k, 5); rm(y, x, k, 4); \
+        rm(y, x, k, 3); rm(y, x, k, 2); \
+        rm(y, x, k, 1); rm(y, x, k, 0); \
+        break; \
+    case 7: rm(y, x, k, 6); rm(y, x, k, 5); \
+        rm(y, x, k, 4); rm(y, x, k, 3); \
+        rm(y, x, k, 2); rm(y, x, k, 1); \
+        rm(y, x, k, 0); \
+        break; \
+    case 6: rm(y, x, k, 5); rm(y, x, k, 4); \
+        rm(y, x, k, 3); rm(y, x, k, 2); \
+        rm(y, x, k, 1); rm(y, x, k, 0); \
+        break; \
+    case 5: rm(y, x, k, 4); rm(y, x, k, 3); \
+        rm(y, x, k, 2); rm(y, x, k, 1); \
+        rm(y, x, k, 0); \
+        break; \
+    case 4: rm(y, x, k, 3); rm(y, x, k, 2); \
+        rm(y, x, k, 1); rm(y, x, k, 0); \
+        break; \
+    }
+#else
+
+#define round(rm, y, x, k) \
+    switch (nc) \
+    {   case 8: rm(y, x, k, 7); \
+    case 7: rm(y, x, k, 6); \
+    case 6: rm(y, x, k, 5); \
+    case 5: rm(y, x, k, 4); \
+    case 4: rm(y, x, k, 3); rm(y, x, k, 2); \
+        rm(y, x, k, 1); rm(y, x, k, 0); \
+    }
+
+#endif
+
+#endif
+#endif
+
+#if defined(ENCRYPTION)
+
+/* I am grateful to Frank Yellin for the following construction
+ * (and that for decryption) which, given the column (c) of the
+ * output state variable, gives the input state variables which
+ * are needed for each row (r) of the state.
+ *
+ * For the fixed block size options, compilers should reduce these
+ * two expressions to fixed variable references. But for variable
+ * block size code conditional clauses will sometimes be returned.
+ *
+ * y = output word, x = input word, r = row, c = column for r = 0,
+ * 1, 2 and 3 = column accessed for row r.
+ */
+
+#define fwd_var(x, r, c) \
+    (r == 0 ?           \
+     (c == 0 ? s(x, 0) \
+     : c == 1 ? s(x, 1) \
+     : c == 2 ? s(x, 2) \
+     : c == 3 ? s(x, 3) \
+     : c == 4 ? s(x, 4) \
+     : c == 5 ? s(x, 5) \
+     : c == 6 ? s(x, 6) \
+     :          s(x, 7)) \
+     : r == 1 ?           \
+     (c == 0 ? s(x, 1) \
+     : c == 1 ? s(x, 2) \
+     : c == 2 ? s(x, 3) \
+     : c == 3 ? nc == 4 ? s(x, 0) : s(x, 4) \
+     : c == 4 ? nc == 5 ? s(x, 0) : s(x, 5) \
+     : c == 5 ? nc == 6 ? s(x, 0) : s(x, 6) \
+     : c == 6 ? nc == 7 ? s(x, 0) : s(x, 7) \
+     :          s(x, 0)) \
+     : r == 2 ?           \
+     (c == 0 ? nc == 8 ? s(x, 3) : s(x, 2) \
+     : c == 1 ? nc == 8 ? s(x, 4) : s(x, 3) \
+     : c == 2 ? nc == 8 ? s(x, 5) : nc == 4 ? s(x, 0) : s(x, 4) \
+     : c == 3 ? nc == 8 ? s(x, 6) : nc == 5 ? s(x, 0) : nc == 4 ? s(x, 1) : 
s(x, 5) \
+     : c == 4 ? nc == 8 ? s(x, 7) : nc == 7 ? s(x, 6) : nc == 6 ? s(x, 0) : 
s(x, 1) \
+     : c == 5 ? nc == 6 ? s(x, 1) : s(x, 0) \
+     : c == 6 ? s(x, 1) \
+     :          s(x, 2)) \
+     :                    \
+     (c == 0 ? nc >  6 ? s(x, 4) : s(x, 3) \
+     : c == 1 ? nc >  6 ? s(x, 5) : nc == 4 ? s(x, 0) : s(x, 4) \
+     : c == 2 ? nc >  6 ? s(x, 6) : nc == 6 ? s(x, 5) : nc == 5 ? s(x, 0) : 
s(x, 1) \
+     : c == 3 ? nc == 8 ? s(x, 7) : nc == 5 ? s(x, 1) : nc == 4 ? s(x, 2) : 
s(x, 0) \
+     : c == 4 ? nc == 8 ? s(x, 0) : nc == 5 ? s(x, 2) : s(x, 1) \
+     : c == 5 ? nc == 8 ? s(x, 1) : s(x, 2) \
+     : c == 6 ? nc == 8 ? s(x, 2) : s(x, 3) \
+     :          s(x, 3)))
+
+#if defined(FT4_SET)
+#undef  dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y, x, k, c)    s(y, c) = (k)[c] ^ four_tables(x, ft_tab, 
fwd_var, rf1, c)
+#elif defined(FT1_SET)
+#undef  dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y, x, k, c)    s(y, c) = (k)[c] ^ one_table(x, upr, ft_tab, 
fwd_var, rf1, c)
+#else
+#define fwd_rnd(y, x, k, c)    s(y, c) = fwd_mcol(no_table(x, s_box, fwd_var, 
rf1, c)) ^ (k)[c]
+#endif
+
+#if defined(FL4_SET)
+#define fwd_lrnd(y, x, k, c)   s(y, c) = (k)[c] ^ four_tables(x, fl_tab, 
fwd_var, rf1, c)
+#elif defined(FL1_SET)
+#define fwd_lrnd(y, x, k, c)   s(y, c) = (k)[c] ^ one_table(x, ups, fl_tab, 
fwd_var, rf1, c)
+#else
+#define fwd_lrnd(y, x, k, c)   s(y, c) = no_table(x, s_box, fwd_var, rf1, c) ^ 
(k)[c]
+#endif
+
+aes_rval aes_enc_blk_(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1])
+{
+    aes_32t        locals(b0, b1);
+    const aes_32t *kp = cx->k_sch;
+    dec_fmvars  /* declare variables for fwd_mcol() if needed */
+
+    if (!(cx->n_blk & 1)) {
+        return aes_bad;
+    }
+
+#if (ENC_UNROLL == FULL)
+
+    state_in((cx->n_rnd & 1 ? b1 : b0), in_blk, kp);
+    kp += (cx->n_rnd - 9) * nc;
+
+    switch (cx->n_rnd) {
+    case 14:    round(fwd_rnd,  b1, b0, kp - 4 * nc);
+    case 13:    round(fwd_rnd,  b0, b1, kp - 3 * nc);
+    case 12:    round(fwd_rnd,  b1, b0, kp - 2 * nc);
+    case 11:    round(fwd_rnd,  b0, b1, kp -     nc);
+    case 10:    round(fwd_rnd,  b1, b0, kp         );
+        round(fwd_rnd,  b0, b1, kp +     nc);
+        round(fwd_rnd,  b1, b0, kp + 2 * nc);
+        round(fwd_rnd,  b0, b1, kp + 3 * nc);
+        round(fwd_rnd,  b1, b0, kp + 4 * nc);
+        round(fwd_rnd,  b0, b1, kp + 5 * nc);
+        round(fwd_rnd,  b1, b0, kp + 6 * nc);
+        round(fwd_rnd,  b0, b1, kp + 7 * nc);
+        round(fwd_rnd,  b1, b0, kp + 8 * nc);
+        round(fwd_lrnd, b0, b1, kp + 9 * nc);
+    }
+#else
+    {   aes_32t rnd;
+
+        state_in(b0, in_blk, kp);
+
+#if (ENC_UNROLL == PARTIAL)
+
+        for (rnd = 0; rnd < (cx->n_rnd - 1) >> 1; ++rnd) {
+            kp += nc;
+            round(fwd_rnd, b1, b0, kp);
+            kp += nc;
+            round(fwd_rnd, b0, b1, kp);
+        }
+
+        if (cx->n_rnd & 1) {
+            l_copy(b1, b0);
+        } else {
+            kp += nc;
+            round(fwd_rnd,  b1, b0, kp);
+        }
+#else
+        for (rnd = 0; rnd < cx->n_rnd - 1; ++rnd) {
+            kp += nc;
+            round(fwd_rnd, b1, b0, kp);
+            l_copy(b0, b1);
+        }
+#endif
+        kp += nc;
+        round(fwd_lrnd, b0, b1, kp);
+    }
+#endif
+
+    state_out(out_blk, b0);
+    return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION)
+
+#define inv_var(x, r, c) \
+    (r == 0 ?           \
+     (c == 0 ? s(x, 0) \
+     : c == 1 ? s(x, 1) \
+     : c == 2 ? s(x, 2) \
+     : c == 3 ? s(x, 3) \
+     : c == 4 ? s(x, 4) \
+     : c == 5 ? s(x, 5) \
+     : c == 6 ? s(x, 6) \
+     :          s(x, 7)) \
+     : r == 1 ?           \
+     (c == 0 ? nc == 8 ? s(x, 7) : nc == 7 ? s(x, 6) : nc == 6 ? s(x, 5) : nc 
== 5 ? s(x, 4) : s(x, 3) \
+     : c == 1 ? s(x, 0) \
+     : c == 2 ? s(x, 1) \
+     : c == 3 ? s(x, 2) \
+     : c == 4 ? s(x, 3) \
+     : c == 5 ? s(x, 4) \
+     : c == 6 ? s(x, 5) \
+     :          s(x, 6)) \
+     : r == 2 ?           \
+     (c == 0 ? nc >  6 ? s(x, 5) : nc == 6 ? s(x, 4) : nc == 5 ? s(x, 3) : 
s(x, 2) \
+     : c == 1 ? nc >  6 ? s(x, 6) : nc == 6 ? s(x, 5) : nc == 5 ? s(x, 4) : 
s(x, 3) \
+     : c == 2 ? nc == 8 ? s(x, 7) : s(x, 0) \
+     : c == 3 ? nc == 8 ? s(x, 0) : s(x, 1) \
+     : c == 4 ? nc == 8 ? s(x, 1) : s(x, 2) \
+     : c == 5 ? nc == 8 ? s(x, 2) : s(x, 3) \
+     : c == 6 ? nc == 8 ? s(x, 3) : s(x, 4) \
+     :          s(x, 4)) \
+     :                    \
+     (c == 0 ? nc == 8 ? s(x, 4) : nc == 5 ? s(x, 2) : nc == 4 ? s(x, 1) : 
s(x, 3) \
+     : c == 1 ? nc == 8 ? s(x, 5) : nc == 5 ? s(x, 3) : nc == 4 ? s(x, 2) : 
s(x, 4) \
+     : c == 2 ? nc == 8 ? s(x, 6) : nc == 5 ? s(x, 4) : nc == 4 ? s(x, 3) : 
s(x, 5) \
+     : c == 3 ? nc == 8 ? s(x, 7) : nc == 7 ? s(x, 6) : s(x, 0) \
+     : c == 4 ? nc >  6 ? s(x, 0) : s(x, 1) \
+     : c == 5 ? nc == 6 ? s(x, 2) : s(x, 1) \
+     : c == 6 ? s(x, 2) \
+     :          s(x, 3)))
+
+#if defined(IT4_SET)
+#undef  dec_imvars
+#define dec_imvars
+#define inv_rnd(y, x, k, c)    s(y, c) = (k)[c] ^ four_tables(x, it_tab, 
inv_var, rf1, c)
+#elif defined(IT1_SET)
+#undef  dec_imvars
+#define dec_imvars
+#define inv_rnd(y, x, k, c)    s(y, c) = (k)[c] ^ one_table(x, upr, it_tab, 
inv_var, rf1, c)
+#else
+#define inv_rnd(y, x, k, c)    s(y, c) = inv_mcol(no_table(x, inv_s_box, 
inv_var, rf1, c) ^ (k)[c])
+#endif
+
+#if defined(IL4_SET)
+#define inv_lrnd(y, x, k, c)   s(y, c) = (k)[c] ^ four_tables(x, il_tab, 
inv_var, rf1, c)
+#elif defined(IL1_SET)
+#define inv_lrnd(y, x, k, c)   s(y, c) = (k)[c] ^ one_table(x, ups, il_tab, 
inv_var, rf1, c)
+#else
+#define inv_lrnd(y, x, k, c)   s(y, c) = no_table(x, inv_s_box, inv_var, rf1, 
c) ^ (k)[c]
+#endif
+
+aes_rval aes_dec_blk_(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1])
+{
+    aes_32t        locals(b0, b1);
+    const aes_32t *kp = cx->k_sch + nc * cx->n_rnd;
+    dec_imvars  /* declare variables for inv_mcol() if needed */
+
+    if (!(cx->n_blk & 2)) {
+        return aes_bad;
+    }
+
+#if (DEC_UNROLL == FULL)
+
+    state_in((cx->n_rnd & 1 ? b1 : b0), in_blk, kp);
+    kp = cx->k_sch + 9 * nc;
+
+    switch (cx->n_rnd) {
+    case 14:    round(inv_rnd,  b1, b0, kp + 4 * nc);
+    case 13:    round(inv_rnd,  b0, b1, kp + 3 * nc);
+    case 12:    round(inv_rnd,  b1, b0, kp + 2 * nc);
+    case 11:    round(inv_rnd,  b0, b1, kp +     nc);
+    case 10:    round(inv_rnd,  b1, b0, kp         );
+        round(inv_rnd,  b0, b1, kp -     nc);
+        round(inv_rnd,  b1, b0, kp - 2 * nc);
+        round(inv_rnd,  b0, b1, kp - 3 * nc);
+        round(inv_rnd,  b1, b0, kp - 4 * nc);
+        round(inv_rnd,  b0, b1, kp - 5 * nc);
+        round(inv_rnd,  b1, b0, kp - 6 * nc);
+        round(inv_rnd,  b0, b1, kp - 7 * nc);
+        round(inv_rnd,  b1, b0, kp - 8 * nc);
+        round(inv_lrnd, b0, b1, kp - 9 * nc);
+    }
+#else
+    {   aes_32t rnd;
+
+        state_in(b0, in_blk, kp);
+
+#if (DEC_UNROLL == PARTIAL)
+
+        for (rnd = 0; rnd < (cx->n_rnd - 1) >> 1; ++rnd) {
+            kp -= nc;
+            round(inv_rnd, b1, b0, kp);
+            kp -= nc;
+            round(inv_rnd, b0, b1, kp);
+        }
+
+        if (cx->n_rnd & 1) {
+            l_copy(b1, b0);
+        } else {
+            kp -= nc;
+            round(inv_rnd,  b1, b0, kp);
+        }
+#else
+        for (rnd = 0; rnd < cx->n_rnd - 1; ++rnd) {
+            kp -= nc;
+            round(inv_rnd, b1, b0, kp);
+            l_copy(b0, b1);
+        }
+#endif
+        kp -= nc;
+        round(inv_lrnd, b0, b1, kp);
+    }
+#endif
+
+    state_out(out_blk, b0);
+    return aes_good;
+}
+
+#endif

=== modified file 'i3/aeshash/aescrypt.c'
--- i3/aeshash/aescrypt.c       2009-12-11 22:49:11 +0000
+++ i3/aeshash/aescrypt.c       2010-02-11 11:49:47 +0000
@@ -1,421 +1,421 @@
-/*
- -------------------------------------------------------------------------
- Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary 
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright 
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products 
-      built using this software without specific written permission. 
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness 
- and fitness for purpose.
- -------------------------------------------------------------------------
- Issue Date: 29/07/2002
-
- This file contains the code for implementing encryption and decryption
- for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It  
- can optionally be replaced by code written in assembler using NASM.
-*/
-
-#include "aesopt.h"
-
-#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
-#error An illegal block size has been specified.
-#endif  
-
-#define unused  77  /* Sunset Strip */
-
-#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
-#define so(y,x,c)   word_out(y + 4 * c, s(x,c))
-
-#if BLOCK_SIZE == 16
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[4],y[4]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
- /* 
-   the following defines prevent the compiler requiring the declaration
-   of generated but unused variables in the fwd_var and inv_var macros
- */
-#define b04 unused
-#define b05 unused
-#define b06 unused
-#define b07 unused
-#define b14 unused
-#define b15 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-
-#elif BLOCK_SIZE == 24
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[6],y[6]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5, \
-                        y##0,y##1,y##2,y##3,y##4,y##5
-#define b06 unused
-#define b07 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
-                        si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); \
-                        so(y,x,3); so(y,x,4); so(y,x,5)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
-                        rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
-#else
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[8],y[8]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
-                        y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5); \
-                        s(y,6) = s(x,6); s(y,7) = s(x,7);
-
-#if BLOCK_SIZE == 32
-
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
-                        si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
-                        so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
-                        rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
-#else
-
-#define state_in(y,x,k) \
-switch(nc) \
-{   case 8: si(y,x,k,7); si(y,x,k,6); \
-    case 6: si(y,x,k,5); si(y,x,k,4); \
-    case 4: si(y,x,k,3); si(y,x,k,2); \
-            si(y,x,k,1); si(y,x,k,0); \
-}
-
-#define state_out(y,x) \
-switch(nc) \
-{   case 8: so(y,x,7); so(y,x,6); \
-    case 6: so(y,x,5); so(y,x,4); \
-    case 4: so(y,x,3); so(y,x,2); \
-            so(y,x,1); so(y,x,0); \
-}
-
-#if defined(FAST_VARIABLE)
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{   case 8: rm(y,x,k,7); rm(y,x,k,6); \
-            rm(y,x,k,5); rm(y,x,k,4); \
-            rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-    case 6: rm(y,x,k,5); rm(y,x,k,4); \
-            rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-    case 4: rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-}
-#else
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{   case 8: rm(y,x,k,7); rm(y,x,k,6); \
-    case 6: rm(y,x,k,5); rm(y,x,k,4); \
-    case 4: rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-}
-
-#endif
-
-#endif
-#endif
-
-#if defined(ENCRYPTION)
-
-/* I am grateful to Frank Yellin for the following construction
-   (and that for decryption) which, given the column (c) of the 
-   output state variable, gives the input state variables which 
-   are needed in its computation for each row (r) of the state.
-
-   For the fixed block size options, compilers should be able to 
-   reduce this complex expression (and the equivalent one for 
-   decryption) to a static variable reference at compile time. 
-   But for variable block size code, there will be some limbs on
-   which conditional clauses will be returned.
-*/
-
-/* y = output word, x = input word, r = row, c = column for r = 0, 
-   1, 2 and 3 = column accessed for row r.
-*/
-
-#define fwd_var(x,r,c)\
- ( r == 0 ?           \
-    ( c == 0 ? s(x,0) \
-    : c == 1 ? s(x,1) \
-    : c == 2 ? s(x,2) \
-    : c == 3 ? s(x,3) \
-    : c == 4 ? s(x,4) \
-    : c == 5 ? s(x,5) \
-    : c == 6 ? s(x,6) \
-    :          s(x,7))\
- : r == 1 ?           \
-    ( c == 0 ? s(x,1) \
-    : c == 1 ? s(x,2) \
-    : c == 2 ? s(x,3) \
-    : c == 3 ? nc == 4 ? s(x,0) : s(x,4) \
-    : c == 4 ? s(x,5) \
-    : c == 5 ? nc == 8 ? s(x,6) : s(x,0) \
-    : c == 6 ? s(x,7) \
-    :          s(x,0))\
- : r == 2 ?           \
-    ( c == 0 ? nc == 8 ? s(x,3) : s(x,2) \
-    : c == 1 ? nc == 8 ? s(x,4) : s(x,3) \
-    : c == 2 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
-    : c == 3 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
-    : c == 4 ? nc == 8 ? s(x,7) : s(x,0) \
-    : c == 5 ? nc == 8 ? s(x,0) : s(x,1) \
-    : c == 6 ? s(x,1) \
-    :          s(x,2))\
- :                    \
-    ( c == 0 ? nc == 8 ? s(x,4) : s(x,3) \
-    : c == 1 ? nc == 4 ? s(x,0) : nc == 8 ? s(x,5) : s(x,4) \
-    : c == 2 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,6) : s(x,5) \
-    : c == 3 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,7) : s(x,0) \
-    : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
-    : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
-    : c == 6 ? s(x,2) \
-    :          s(x,3)))
-
-#if defined(FT4_SET)
-#undef  dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ 
four_tables(x,ft_tab,fwd_var,rf1,c)
-#elif defined(FT1_SET)
-#undef  dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ 
one_table(x,upr,ft_tab,fwd_var,rf1,c)
-#else
-#define fwd_rnd(y,x,k,c)    s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) 
^ (k)[c]
-#endif
-
-#if defined(FL4_SET)
-#define fwd_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ 
four_tables(x,fl_tab,fwd_var,rf1,c)
-#elif defined(FL1_SET)
-#define fwd_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ 
one_table(x,ups,fl_tab,fwd_var,rf1,c)
-#else
-#define fwd_lrnd(y,x,k,c)   s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
-#endif
-
-aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1])
-{   aes_32t        locals(b0, b1);
-    const aes_32t  *kp = cx->k_sch;
-    dec_fmvars  /* declare variables for fwd_mcol() if needed */
-
-    if(!(cx->n_blk & 1)) return aes_bad;
-
-    state_in(b0, in_blk, kp); 
-
-#if (ENC_UNROLL == FULL)
-
-    kp += (cx->n_rnd - 9) * nc;
-
-    switch(cx->n_rnd)
-    {
-    case 14:    round(fwd_rnd,  b1, b0, kp - 4 * nc); 
-                round(fwd_rnd,  b0, b1, kp - 3 * nc);
-    case 12:    round(fwd_rnd,  b1, b0, kp - 2 * nc); 
-                round(fwd_rnd,  b0, b1, kp -     nc);
-    case 10:    round(fwd_rnd,  b1, b0, kp         );             
-                round(fwd_rnd,  b0, b1, kp +     nc);
-                round(fwd_rnd,  b1, b0, kp + 2 * nc); 
-                round(fwd_rnd,  b0, b1, kp + 3 * nc);
-                round(fwd_rnd,  b1, b0, kp + 4 * nc); 
-                round(fwd_rnd,  b0, b1, kp + 5 * nc);
-                round(fwd_rnd,  b1, b0, kp + 6 * nc); 
-                round(fwd_rnd,  b0, b1, kp + 7 * nc);
-                round(fwd_rnd,  b1, b0, kp + 8 * nc);
-                round(fwd_lrnd, b0, b1, kp + 9 * nc);
-    }
-#else
-    
-#if (ENC_UNROLL == PARTIAL)
-    {   aes_32t    rnd;
-        for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
-        {
-            kp += nc;
-            round(fwd_rnd, b1, b0, kp); 
-            kp += nc;
-            round(fwd_rnd, b0, b1, kp); 
-        }
-        kp += nc;
-        round(fwd_rnd,  b1, b0, kp);
-#else
-    {   aes_32t    rnd, *p0 = b0, *p1 = b1, *pt;
-        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
-        {
-            kp += nc;
-            round(fwd_rnd, p1, p0, kp); 
-            pt = p0, p0 = p1, p1 = pt;
-        }
-#endif
-        kp += nc;
-        round(fwd_lrnd, b0, b1, kp);
-    }
-#endif
-
-    state_out(out_blk, b0);
-    return aes_good;
-}
-
-#endif
-
-#if defined(DECRYPTION)
-
-#define inv_var(x,r,c) \
- ( r == 0 ?           \
-    ( c == 0 ? s(x,0) \
-    : c == 1 ? s(x,1) \
-    : c == 2 ? s(x,2) \
-    : c == 3 ? s(x,3) \
-    : c == 4 ? s(x,4) \
-    : c == 5 ? s(x,5) \
-    : c == 6 ? s(x,6) \
-    :          s(x,7))\
- : r == 1 ?           \
-    ( c == 0 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,7) : s(x,5) \
-    : c == 1 ? s(x,0) \
-    : c == 2 ? s(x,1) \
-    : c == 3 ? s(x,2) \
-    : c == 4 ? s(x,3) \
-    : c == 5 ? s(x,4) \
-    : c == 6 ? s(x,5) \
-    :          s(x,6))\
- : r == 2 ?           \
-    ( c == 0 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
-    : c == 1 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
-    : c == 2 ? nc == 8 ? s(x,7) : s(x,0) \
-    : c == 3 ? nc == 8 ? s(x,0) : s(x,1) \
-    : c == 4 ? nc == 8 ? s(x,1) : s(x,2) \
-    : c == 5 ? nc == 8 ? s(x,2) : s(x,3) \
-    : c == 6 ? s(x,3) \
-    :          s(x,4))\
- :                    \
-    ( c == 0 ? nc == 4 ? s(x,1) : nc == 8 ? s(x,4) : s(x,3) \
-    : c == 1 ? nc == 4 ? s(x,2) : nc == 8 ? s(x,5) : s(x,4) \
-    : c == 2 ? nc == 4 ? s(x,3) : nc == 8 ? s(x,6) : s(x,5) \
-    : c == 3 ? nc == 8 ? s(x,7) : s(x,0) \
-    : c == 4 ? nc == 8 ? s(x,0) : s(x,1) \
-    : c == 5 ? nc == 8 ? s(x,1) : s(x,2) \
-    : c == 6 ? s(x,2) \
-    :          s(x,3)))
-
-#if defined(IT4_SET)
-#undef  dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ 
four_tables(x,it_tab,inv_var,rf1,c)
-#elif defined(IT1_SET)
-#undef  dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ 
one_table(x,upr,it_tab,inv_var,rf1,c)
-#else
-#define inv_rnd(y,x,k,c)    s(y,c) = 
inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
-#endif
-
-#if defined(IL4_SET)
-#define inv_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ 
four_tables(x,il_tab,inv_var,rf1,c)
-#elif defined(IL1_SET)
-#define inv_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ 
one_table(x,ups,il_tab,inv_var,rf1,c)
-#else
-#define inv_lrnd(y,x,k,c)   s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ 
(k)[c]
-#endif
-
-aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1])
-{   aes_32t        locals(b0, b1);
-    const aes_32t  *kp = cx->k_sch + nc * cx->n_rnd;
-    dec_imvars  /* declare variables for inv_mcol() if needed */
-
-    if(!(cx->n_blk & 2)) return aes_bad;
-
-    state_in(b0, in_blk, kp);
-
-#if (DEC_UNROLL == FULL)
-
-    kp = cx->k_sch + 9 * nc;
-    switch(cx->n_rnd)
-    {
-    case 14:    round(inv_rnd,  b1, b0, kp + 4 * nc);
-                round(inv_rnd,  b0, b1, kp + 3 * nc);
-    case 12:    round(inv_rnd,  b1, b0, kp + 2 * nc);
-                round(inv_rnd,  b0, b1, kp + nc    );
-    case 10:    round(inv_rnd,  b1, b0, kp         );             
-                round(inv_rnd,  b0, b1, kp -     nc);
-                round(inv_rnd,  b1, b0, kp - 2 * nc); 
-                round(inv_rnd,  b0, b1, kp - 3 * nc);
-                round(inv_rnd,  b1, b0, kp - 4 * nc); 
-                round(inv_rnd,  b0, b1, kp - 5 * nc);
-                round(inv_rnd,  b1, b0, kp - 6 * nc); 
-                round(inv_rnd,  b0, b1, kp - 7 * nc);
-                round(inv_rnd,  b1, b0, kp - 8 * nc);
-                round(inv_lrnd, b0, b1, kp - 9 * nc);
-    }
-#else
-    
-#if (DEC_UNROLL == PARTIAL)
-    {   aes_32t    rnd;
-        for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
-        {
-            kp -= nc; 
-            round(inv_rnd, b1, b0, kp); 
-            kp -= nc; 
-            round(inv_rnd, b0, b1, kp); 
-        }
-        kp -= nc;
-        round(inv_rnd, b1, b0, kp);
-#else
-    {   aes_32t    rnd, *p0 = b0, *p1 = b1, *pt;
-        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
-        {
-            kp -= nc;
-            round(inv_rnd, p1, p0, kp); 
-            pt = p0, p0 = p1, p1 = pt;
-        }
-#endif
-        kp -= nc;
-        round(inv_lrnd, b0, b1, kp);
-    }
-#endif
-
-    state_out(out_blk, b0);
-    return aes_good;
-}
-
-#endif
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ *    notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ *    built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ * -------------------------------------------------------------------------
+ * Issue Date: 29/07/2002
+ *
+ * This file contains the code for implementing encryption and decryption
+ * for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
+ * can optionally be replaced by code written in assembler using NASM.
+ */
+
+#include "aesopt.h"
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+#define unused  77  /* Sunset Strip */
+
+#define si(y, x, k, c) s(y, c) = word_in(x + 4 * c) ^ k[c]
+#define so(y, x, c)   word_out(y + 4 * c, s(x, c))
+
+#if BLOCK_SIZE == 16
+
+#if defined(ARRAYS)
+#define locals(y, x)     x[4], y[4]
+#else
+#define locals(y, x)     x ## 0, x ## 1, x ## 2, x ## 3, y ## 0, y ## 1, y ## 
2, y ## 3
+/*
+ * the following defines prevent the compiler requiring the declaration
+ * of generated but unused variables in the fwd_var and inv_var macros
+ */
+#define b04 unused
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b14 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x)    s(y, 0) = s(x, 0); s(y, 1) = s(x, 1); \
+    s(y, 2)                     = s(x, 2); s(y, 3) = s(x, 3);
+#define state_in(y, x, k) si(y, x, k, 0); si(y, x, k, 1); si(y, x, k, 2); 
si(y, x, k, 3)
+#define state_out(y, x)  so(y, x, 0); so(y, x, 1); so(y, x, 2); so(y, x, 3)
+#define round(rm, y, x, k) rm(y, x, k, 0); rm(y, x, k, 1); rm(y, x, k, 2); 
rm(y, x, k, 3)
+
+#elif BLOCK_SIZE == 24
+
+#if defined(ARRAYS)
+#define locals(y, x)     x[6], y[6]
+#else
+#define locals(y, x)     x ## 0, x ## 1, x ## 2, x ## 3, x ## 4, x ## 5, \
+    y ## 0, y ## 1, y ## 2, y ## 3, y ## 4, y ## 5
+#define b06 unused
+#define b07 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x)    s(y, 0) = s(x, 0); s(y, 1) = s(x, 1); \
+    s(y, 2)                     = s(x, 2); s(y, 3) = s(x, 3); \
+    s(y, 4)                     = s(x, 4); s(y, 5) = s(x, 5);
+#define state_in(y, x, k) si(y, x, k, 0); si(y, x, k, 1); si(y, x, k, 2); \
+    si(y, x, k, 3); si(y, x, k, 4); si(y, x, k, 5)
+#define state_out(y, x)  so(y, x, 0); so(y, x, 1); so(y, x, 2); \
+    so(y, x, 3); so(y, x, 4); so(y, x, 5)
+#define round(rm, y, x, k) rm(y, x, k, 0); rm(y, x, k, 1); rm(y, x, k, 2); \
+    rm(y, x, k, 3); rm(y, x, k, 4); rm(y, x, k, 5)
+#else
+
+#if defined(ARRAYS)
+#define locals(y, x)     x[8], y[8]
+#else
+#define locals(y, x)     x ## 0, x ## 1, x ## 2, x ## 3, x ## 4, x ## 5, x ## 
6, x ## 7, \
+    y ## 0, y ## 1, y ## 2, y ## 3, y ## 4, y ## 5, y ## 6, y ## 7
+#endif
+#define l_copy(y, x)    s(y, 0) = s(x, 0); s(y, 1) = s(x, 1); \
+    s(y, 2)                     = s(x, 2); s(y, 3) = s(x, 3); \
+    s(y, 4)                     = s(x, 4); s(y, 5) = s(x, 5); \
+    s(y, 6)                     = s(x, 6); s(y, 7) = s(x, 7);
+
+#if BLOCK_SIZE == 32
+
+#define state_in(y, x, k) si(y, x, k, 0); si(y, x, k, 1); si(y, x, k, 2); 
si(y, x, k, 3); \
+    si(y, x, k, 4); si(y, x, k, 5); si(y, x, k, 6); si(y, x, k, 7)
+#define state_out(y, x)  so(y, x, 0); so(y, x, 1); so(y, x, 2); so(y, x, 3); \
+    so(y, x, 4); so(y, x, 5); so(y, x, 6); so(y, x, 7)
+#define round(rm, y, x, k) rm(y, x, k, 0); rm(y, x, k, 1); rm(y, x, k, 2); 
rm(y, x, k, 3); \
+    rm(y, x, k, 4); rm(y, x, k, 5); rm(y, x, k, 6); rm(y, x, k, 7)
+#else
+
+#define state_in(y, x, k) \
+    switch (nc) \
+    {   case 8: si(y, x, k, 7); si(y, x, k, 6); \
+    case 6: si(y, x, k, 5); si(y, x, k, 4); \
+    case 4: si(y, x, k, 3); si(y, x, k, 2); \
+        si(y, x, k, 1); si(y, x, k, 0); \
+    }
+
+#define state_out(y, x) \
+    switch (nc) \
+    {   case 8: so(y, x, 7); so(y, x, 6); \
+    case 6: so(y, x, 5); so(y, x, 4); \
+    case 4: so(y, x, 3); so(y, x, 2); \
+        so(y, x, 1); so(y, x, 0); \
+    }
+
+#if defined(FAST_VARIABLE)
+
+#define round(rm, y, x, k) \
+    switch (nc) \
+    {   case 8: rm(y, x, k, 7); rm(y, x, k, 6); \
+        rm(y, x, k, 5); rm(y, x, k, 4); \
+        rm(y, x, k, 3); rm(y, x, k, 2); \
+        rm(y, x, k, 1); rm(y, x, k, 0); \
+        break; \
+    case 6: rm(y, x, k, 5); rm(y, x, k, 4); \
+        rm(y, x, k, 3); rm(y, x, k, 2); \
+        rm(y, x, k, 1); rm(y, x, k, 0); \
+        break; \
+    case 4: rm(y, x, k, 3); rm(y, x, k, 2); \
+        rm(y, x, k, 1); rm(y, x, k, 0); \
+        break; \
+    }
+#else
+
+#define round(rm, y, x, k) \
+    switch (nc) \
+    {   case 8: rm(y, x, k, 7); rm(y, x, k, 6); \
+    case 6: rm(y, x, k, 5); rm(y, x, k, 4); \
+    case 4: rm(y, x, k, 3); rm(y, x, k, 2); \
+        rm(y, x, k, 1); rm(y, x, k, 0); \
+    }
+
+#endif
+
+#endif
+#endif
+
+#if defined(ENCRYPTION)
+
+/* I am grateful to Frank Yellin for the following construction
+ * (and that for decryption) which, given the column (c) of the
+ * output state variable, gives the input state variables which
+ * are needed in its computation for each row (r) of the state.
+ *
+ * For the fixed block size options, compilers should be able to
+ * reduce this complex expression (and the equivalent one for
+ * decryption) to a static variable reference at compile time.
+ * But for variable block size code, there will be some limbs on
+ * which conditional clauses will be returned.
+ */
+
+/* y = output word, x = input word, r = row, c = column for r = 0,
+ * 1, 2 and 3 = column accessed for row r.
+ */
+
+#define fwd_var(x, r, c) \
+    (r == 0 ?           \
+     (c == 0 ? s(x, 0) \
+     : c == 1 ? s(x, 1) \
+     : c == 2 ? s(x, 2) \
+     : c == 3 ? s(x, 3) \
+     : c == 4 ? s(x, 4) \
+     : c == 5 ? s(x, 5) \
+     : c == 6 ? s(x, 6) \
+     :          s(x, 7)) \
+     : r == 1 ?           \
+     (c == 0 ? s(x, 1) \
+     : c == 1 ? s(x, 2) \
+     : c == 2 ? s(x, 3) \
+     : c == 3 ? nc == 4 ? s(x, 0) : s(x, 4) \
+     : c == 4 ? s(x, 5) \
+     : c == 5 ? nc == 8 ? s(x, 6) : s(x, 0) \
+     : c == 6 ? s(x, 7) \
+     :          s(x, 0)) \
+     : r == 2 ?           \
+     (c == 0 ? nc == 8 ? s(x, 3) : s(x, 2) \
+     : c == 1 ? nc == 8 ? s(x, 4) : s(x, 3) \
+     : c == 2 ? nc == 4 ? s(x, 0) : nc == 8 ? s(x, 5) : s(x, 4) \
+     : c == 3 ? nc == 4 ? s(x, 1) : nc == 8 ? s(x, 6) : s(x, 5) \
+     : c == 4 ? nc == 8 ? s(x, 7) : s(x, 0) \
+     : c == 5 ? nc == 8 ? s(x, 0) : s(x, 1) \
+     : c == 6 ? s(x, 1) \
+     :          s(x, 2)) \
+     :                    \
+     (c == 0 ? nc == 8 ? s(x, 4) : s(x, 3) \
+     : c == 1 ? nc == 4 ? s(x, 0) : nc == 8 ? s(x, 5) : s(x, 4) \
+     : c == 2 ? nc == 4 ? s(x, 1) : nc == 8 ? s(x, 6) : s(x, 5) \
+     : c == 3 ? nc == 4 ? s(x, 2) : nc == 8 ? s(x, 7) : s(x, 0) \
+     : c == 4 ? nc == 8 ? s(x, 0) : s(x, 1) \
+     : c == 5 ? nc == 8 ? s(x, 1) : s(x, 2) \
+     : c == 6 ? s(x, 2) \
+     :          s(x, 3)))
+
+#if defined(FT4_SET)
+#undef  dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y, x, k, c)    s(y, c) = (k)[c] ^ four_tables(x, ft_tab, 
fwd_var, rf1, c)
+#elif defined(FT1_SET)
+#undef  dec_fmvars
+#define dec_fmvars
+#define fwd_rnd(y, x, k, c)    s(y, c) = (k)[c] ^ one_table(x, upr, ft_tab, 
fwd_var, rf1, c)
+#else
+#define fwd_rnd(y, x, k, c)    s(y, c) = fwd_mcol(no_table(x, s_box, fwd_var, 
rf1, c)) ^ (k)[c]
+#endif
+
+#if defined(FL4_SET)
+#define fwd_lrnd(y, x, k, c)   s(y, c) = (k)[c] ^ four_tables(x, fl_tab, 
fwd_var, rf1, c)
+#elif defined(FL1_SET)
+#define fwd_lrnd(y, x, k, c)   s(y, c) = (k)[c] ^ one_table(x, ups, fl_tab, 
fwd_var, rf1, c)
+#else
+#define fwd_lrnd(y, x, k, c)   s(y, c) = no_table(x, s_box, fwd_var, rf1, c) ^ 
(k)[c]
+#endif
+
+aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1])
+{
+    aes_32t        locals(b0, b1);
+    const aes_32t *kp = cx->k_sch;
+    dec_fmvars  /* declare variables for fwd_mcol() if needed */
+
+    if (!(cx->n_blk & 1)) {
+        return aes_bad;
+    }
+
+    state_in(b0, in_blk, kp);
+
+#if (ENC_UNROLL == FULL)
+
+    kp += (cx->n_rnd - 9) * nc;
+
+    switch (cx->n_rnd) {
+    case 14:    round(fwd_rnd,  b1, b0, kp - 4 * nc);
+        round(fwd_rnd,  b0, b1, kp - 3 * nc);
+    case 12:    round(fwd_rnd,  b1, b0, kp - 2 * nc);
+        round(fwd_rnd,  b0, b1, kp -     nc);
+    case 10:    round(fwd_rnd,  b1, b0, kp         );
+        round(fwd_rnd,  b0, b1, kp +     nc);
+        round(fwd_rnd,  b1, b0, kp + 2 * nc);
+        round(fwd_rnd,  b0, b1, kp + 3 * nc);
+        round(fwd_rnd,  b1, b0, kp + 4 * nc);
+        round(fwd_rnd,  b0, b1, kp + 5 * nc);
+        round(fwd_rnd,  b1, b0, kp + 6 * nc);
+        round(fwd_rnd,  b0, b1, kp + 7 * nc);
+        round(fwd_rnd,  b1, b0, kp + 8 * nc);
+        round(fwd_lrnd, b0, b1, kp + 9 * nc);
+    }
+#else
+
+#if (ENC_UNROLL == PARTIAL)
+    {   aes_32t rnd;
+        for (rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd) {
+            kp += nc;
+            round(fwd_rnd, b1, b0, kp);
+            kp += nc;
+            round(fwd_rnd, b0, b1, kp);
+        }
+        kp += nc;
+        round(fwd_rnd,  b1, b0, kp);
+#else
+    {   aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
+        for (rnd = 0; rnd < cx->n_rnd - 1; ++rnd) {
+            kp += nc;
+            round(fwd_rnd, p1, p0, kp);
+            pt  = p0, p0 = p1, p1 = pt;
+        }
+#endif
+        kp += nc;
+        round(fwd_lrnd, b0, b1, kp);
+    }
+#endif
+
+    state_out(out_blk, b0);
+    return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION)
+
+#define inv_var(x, r, c) \
+    (r == 0 ?           \
+     (c == 0 ? s(x, 0) \
+     : c == 1 ? s(x, 1) \
+     : c == 2 ? s(x, 2) \
+     : c == 3 ? s(x, 3) \
+     : c == 4 ? s(x, 4) \
+     : c == 5 ? s(x, 5) \
+     : c == 6 ? s(x, 6) \
+     :          s(x, 7)) \
+     : r == 1 ?           \
+     (c == 0 ? nc == 4 ? s(x, 3) : nc == 8 ? s(x, 7) : s(x, 5) \
+     : c == 1 ? s(x, 0) \
+     : c == 2 ? s(x, 1) \
+     : c == 3 ? s(x, 2) \
+     : c == 4 ? s(x, 3) \
+     : c == 5 ? s(x, 4) \
+     : c == 6 ? s(x, 5) \
+     :          s(x, 6)) \
+     : r == 2 ?           \
+     (c == 0 ? nc == 4 ? s(x, 2) : nc == 8 ? s(x, 5) : s(x, 4) \
+     : c == 1 ? nc == 4 ? s(x, 3) : nc == 8 ? s(x, 6) : s(x, 5) \
+     : c == 2 ? nc == 8 ? s(x, 7) : s(x, 0) \
+     : c == 3 ? nc == 8 ? s(x, 0) : s(x, 1) \
+     : c == 4 ? nc == 8 ? s(x, 1) : s(x, 2) \
+     : c == 5 ? nc == 8 ? s(x, 2) : s(x, 3) \
+     : c == 6 ? s(x, 3) \
+     :          s(x, 4)) \
+     :                    \
+     (c == 0 ? nc == 4 ? s(x, 1) : nc == 8 ? s(x, 4) : s(x, 3) \
+     : c == 1 ? nc == 4 ? s(x, 2) : nc == 8 ? s(x, 5) : s(x, 4) \
+     : c == 2 ? nc == 4 ? s(x, 3) : nc == 8 ? s(x, 6) : s(x, 5) \
+     : c == 3 ? nc == 8 ? s(x, 7) : s(x, 0) \
+     : c == 4 ? nc == 8 ? s(x, 0) : s(x, 1) \
+     : c == 5 ? nc == 8 ? s(x, 1) : s(x, 2) \
+     : c == 6 ? s(x, 2) \
+     :          s(x, 3)))
+
+#if defined(IT4_SET)
+#undef  dec_imvars
+#define dec_imvars
+#define inv_rnd(y, x, k, c)    s(y, c) = (k)[c] ^ four_tables(x, it_tab, 
inv_var, rf1, c)
+#elif defined(IT1_SET)
+#undef  dec_imvars
+#define dec_imvars
+#define inv_rnd(y, x, k, c)    s(y, c) = (k)[c] ^ one_table(x, upr, it_tab, 
inv_var, rf1, c)
+#else
+#define inv_rnd(y, x, k, c)    s(y, c) = inv_mcol(no_table(x, inv_s_box, 
inv_var, rf1, c) ^ (k)[c])
+#endif
+
+#if defined(IL4_SET)
+#define inv_lrnd(y, x, k, c)   s(y, c) = (k)[c] ^ four_tables(x, il_tab, 
inv_var, rf1, c)
+#elif defined(IL1_SET)
+#define inv_lrnd(y, x, k, c)   s(y, c) = (k)[c] ^ one_table(x, ups, il_tab, 
inv_var, rf1, c)
+#else
+#define inv_lrnd(y, x, k, c)   s(y, c) = no_table(x, inv_s_box, inv_var, rf1, 
c) ^ (k)[c]
+#endif
+
+aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], 
const aes_ctx cx[1])
+{
+    aes_32t        locals(b0, b1);
+    const aes_32t *kp = cx->k_sch + nc * cx->n_rnd;
+    dec_imvars  /* declare variables for inv_mcol() if needed */
+
+    if (!(cx->n_blk & 2)) {
+        return aes_bad;
+    }
+
+    state_in(b0, in_blk, kp);
+
+#if (DEC_UNROLL == FULL)
+
+    kp = cx->k_sch + 9 * nc;
+    switch (cx->n_rnd) {
+    case 14:    round(inv_rnd,  b1, b0, kp + 4 * nc);
+        round(inv_rnd,  b0, b1, kp + 3 * nc);
+    case 12:    round(inv_rnd,  b1, b0, kp + 2 * nc);
+        round(inv_rnd,  b0, b1, kp + nc    );
+    case 10:    round(inv_rnd,  b1, b0, kp         );
+        round(inv_rnd,  b0, b1, kp -     nc);
+        round(inv_rnd,  b1, b0, kp - 2 * nc);
+        round(inv_rnd,  b0, b1, kp - 3 * nc);
+        round(inv_rnd,  b1, b0, kp - 4 * nc);
+        round(inv_rnd,  b0, b1, kp - 5 * nc);
+        round(inv_rnd,  b1, b0, kp - 6 * nc);
+        round(inv_rnd,  b0, b1, kp - 7 * nc);
+        round(inv_rnd,  b1, b0, kp - 8 * nc);
+        round(inv_lrnd, b0, b1, kp - 9 * nc);
+    }
+#else
+
+#if (DEC_UNROLL == PARTIAL)
+    {   aes_32t rnd;
+        for (rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd) {
+            kp -= nc;
+            round(inv_rnd, b1, b0, kp);
+            kp -= nc;
+            round(inv_rnd, b0, b1, kp);
+        }
+        kp -= nc;
+        round(inv_rnd, b1, b0, kp);
+#else
+    {   aes_32t rnd, *p0 = b0, *p1 = b1, *pt;
+        for (rnd = 0; rnd < cx->n_rnd - 1; ++rnd) {
+            kp -= nc;
+            round(inv_rnd, p1, p0, kp);
+            pt  = p0, p0 = p1, p1 = pt;
+        }
+#endif
+        kp -= nc;
+        round(inv_lrnd, b0, b1, kp);
+    }
+#endif
+
+    state_out(out_blk, b0);
+    return aes_good;
+}
+
+#endif

=== modified file 'i3/aeshash/aeshash.c'
--- i3/aeshash/aeshash.c        2009-12-11 22:49:11 +0000
+++ i3/aeshash/aeshash.c        2010-02-11 11:49:47 +0000
@@ -1,45 +1,48 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h> 
-
-#include "aes.h"
-
-enum {
-  l_c = 0,
-  r_c = 1
-};
-
-static const unsigned char key[2][32] = {{0x23, 0xce, 0x45, 0x19, 0xc5, 0xb6, 
0xb5, 0x82,
-                                0x19, 0x14, 0x36, 0x26, 0xa4, 0xe0, 0x9c, 
0xa2},
-                               {0x20, 0xce, 0x49, 0x19, 0xc5, 0xb6, 0xd5, 0xe2,
-                                0xb6, 0x1d, 0xf6, 0x56, 0xa5, 0xef, 0xfc, 
0xe2}};
-static aes_ctx ctx[2];
-
-void aeshash_type(const unsigned char in[], unsigned char out[], int type)
-{
-  memset(out, 0, BLOCK_SIZE);
-  aes_enc_blk(in, out, ctx + type);
-  ((unsigned __int64 *) out)[0] ^= ((unsigned __int64 *) in)[0];
-  ((unsigned __int64 *) out)[1] ^= ((unsigned __int64 *) in)[1];
-}
-void aeshash_l(const unsigned char in[], unsigned char out[])
-{
-  aeshash_type(in, out, l_c);
-}
-void aeshash_r(const unsigned char in[], unsigned char out[])
-{
-  aeshash_type(in, out, r_c);
-}
-
-void aeshash_init_type(int type)
-{
-  ctx[type].n_rnd = 0; // ensure all flags are initially set to zero
-  ctx[type].n_blk = 0;
-  aes_enc_key(key[type], 16, ctx + type);
-}
-void aeshash_init(void)
-{
-  aeshash_init_type(l_c);
-  aeshash_init_type(r_c);
-}
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "aes.h"
+
+enum {
+    l_c = 0,
+    r_c = 1
+};
+
+static const unsigned char key[2][32] = {{0x23, 0xce, 0x45, 0x19, 0xc5, 0xb6, 
0xb5, 0x82,
+                                          0x19, 0x14, 0x36, 0x26, 0xa4, 0xe0, 
0x9c, 0xa2},
+                                         {0x20, 0xce, 0x49, 0x19, 0xc5, 0xb6, 
0xd5, 0xe2,
+                                          0xb6, 0x1d, 0xf6, 0x56, 0xa5, 0xef, 
0xfc, 0xe2}};
+static aes_ctx ctx[2];
+
+void aeshash_type(const unsigned char in[], unsigned char out[], int type)
+{
+    memset(out, 0, BLOCK_SIZE);
+    aes_enc_blk(in, out, ctx + type);
+    ((unsigned __int64 *) out)[0] ^= ((unsigned __int64 *) in)[0];
+    ((unsigned __int64 *) out)[1] ^= ((unsigned __int64 *) in)[1];
+}
+
+void aeshash_l(const unsigned char in[], unsigned char out[])
+{
+    aeshash_type(in, out, l_c);
+}
+
+void aeshash_r(const unsigned char in[], unsigned char out[])
+{
+    aeshash_type(in, out, r_c);
+}
+
+void aeshash_init_type(int type)
+{
+    ctx[type].n_rnd = 0; // ensure all flags are initially set to zero
+    ctx[type].n_blk = 0;
+    aes_enc_key(key[type], 16, ctx + type);
+}
+
+void aeshash_init(void)
+{
+    aeshash_init_type(l_c);
+    aeshash_init_type(r_c);
+}

=== modified file 'i3/aeshash/aeskey.c'
--- i3/aeshash/aeskey.c 2009-12-11 22:49:11 +0000
+++ i3/aeshash/aeskey.c 2010-02-11 11:49:47 +0000
@@ -1,363 +1,412 @@
-/*
- -------------------------------------------------------------------------
- Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary 
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright 
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products 
-      built using this software without specific written permission. 
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness 
- and fitness for purpose.
- -------------------------------------------------------------------------
- Issue Date: 29/07/2002
-
- This file contains the code for implementing the key schedule for AES 
- (Rijndael) for block and key sizes of 16, 24, and 32 bytes.
-*/
-
-#include "aesopt.h"
-
-#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
-#error An illegal block size has been specified.
-#endif  
-
-/* Subroutine to set the block size (if variable) in bytes, legal
-   values being 16, 24 and 32. 
-*/
-
-#if !defined(BLOCK_SIZE)
-
-aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
-{
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-    if((blen & 7) || blen < 16 || blen > 32) 
-    {     
-        cx->n_blk = 0; return aes_bad;
-    }
-
-    cx->n_blk = blen;
-    return aes_good;
-}
-
-#endif
-
-/* Initialise the key schedule from the user supplied key. The key
-   length is now specified in bytes - 16, 24 or 32 as appropriate.
-   This corresponds to bit lengths of 128, 192 and 256 bits, and
-   to Nk values of 4, 6 and 8 respectively.
-
-   The following macros implement a single cycle in the key 
-   schedule generation process. The number of cycles needed 
-   for each cx->n_col and nk value is:
- 
-    nk =             4  5  6  7  8
-    ------------------------------
-    cx->n_col = 4   10  9  8  7  7
-    cx->n_col = 5   14 11 10  9  9
-    cx->n_col = 6   19 15 12 11 11
-    cx->n_col = 7   21 19 16 13 14
-    cx->n_col = 8   29 23 19 17 14
-*/
-
-#define ke4(k,i) \
-{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= 
ss[0]; \
-    k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
-}
-#define kel4(k,i) \
-{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= 
ss[0]; \
-    k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
-}
-
-#define ke6(k,i) \
-{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] 
^= ss[0]; \
-    k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
-    k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
-}
-#define kel6(k,i) \
-{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] 
^= ss[0]; \
-    k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
-}
-
-#define ke8(k,i) \
-{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] 
^= ss[0]; \
-    k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
-    k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
-    k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
-}
-#define kel8(k,i) \
-{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] 
^= ss[0]; \
-    k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
-}
-
-#if defined(ENCRYPTION_KEY_SCHEDULE)
-
-aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1])
-{   aes_32t    ss[8]; 
-
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-#if !defined(BLOCK_SIZE)
-    if(!cx->n_blk) cx->n_blk = 16;
-#else
-    cx->n_blk = BLOCK_SIZE;
-#endif
-    
-    cx->n_blk = (cx->n_blk & ~3) | 1;
-
-    cx->k_sch[0] = ss[0] = word_in(in_key     );
-    cx->k_sch[1] = ss[1] = word_in(in_key +  4);
-    cx->k_sch[2] = ss[2] = word_in(in_key +  8);
-    cx->k_sch[3] = ss[3] = word_in(in_key + 12);
-
-#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE)
-
-    switch(klen)
-    {
-    case 16:    ke4(cx->k_sch, 0); ke4(cx->k_sch, 1); 
-                ke4(cx->k_sch, 2); ke4(cx->k_sch, 3);
-                ke4(cx->k_sch, 4); ke4(cx->k_sch, 5); 
-                ke4(cx->k_sch, 6); ke4(cx->k_sch, 7);
-                ke4(cx->k_sch, 8); kel4(cx->k_sch, 9); 
-                cx->n_rnd = 10; break;
-    case 24:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                ke6(cx->k_sch, 0); ke6(cx->k_sch, 1); 
-                ke6(cx->k_sch, 2); ke6(cx->k_sch, 3);
-                ke6(cx->k_sch, 4); ke6(cx->k_sch, 5); 
-                ke6(cx->k_sch, 6); kel6(cx->k_sch, 7); 
-                cx->n_rnd = 12; break;
-    case 32:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                cx->k_sch[6] = ss[6] = word_in(in_key + 24);
-                cx->k_sch[7] = ss[7] = word_in(in_key + 28);
-                ke8(cx->k_sch, 0); ke8(cx->k_sch, 1); 
-                ke8(cx->k_sch, 2); ke8(cx->k_sch, 3);
-                ke8(cx->k_sch, 4); ke8(cx->k_sch, 5); 
-                kel8(cx->k_sch, 6); 
-                cx->n_rnd = 14; break;
-    default:    cx->n_rnd = 0; return aes_bad; 
-    }
-#else
-    {   aes_32t i, l;
-        cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-        l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
-
-        switch(klen)
-        {
-        case 16:    for(i = 0; i < l; ++i)
-                        ke4(cx->k_sch, i);
-                    break;
-        case 24:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                    cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                    for(i = 0; i < l; ++i)
-                        ke6(cx->k_sch, i);
-                    break;
-        case 32:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                    cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                    cx->k_sch[6] = ss[6] = word_in(in_key + 24);
-                    cx->k_sch[7] = ss[7] = word_in(in_key + 28);
-                    for(i = 0; i < l; ++i)
-                        ke8(cx->k_sch,  i);
-                    break;
-        default:    cx->n_rnd = 0; return aes_bad; 
-        }
-    }
-#endif
-
-    return aes_good;
-}
-
-#endif
-
-#if defined(DECRYPTION_KEY_SCHEDULE)
-
-#if (DEC_ROUND != NO_TABLES)
-#define d_vars  dec_imvars
-#define ff(x)   inv_mcol(x)
-#else
-#define ff(x)   (x)
-#define d_vars
-#endif
-
-#if 1
-#define kdf4(k,i) \
-{   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = 
ss[2] ^ ss[3]; ss[3] = ss[3]; \
-    ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
-    ss[4] ^= k[4*(i)];   k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; 
k[4*(i)+5] = ff(ss[4]); \
-    ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; 
k[4*(i)+7] = ff(ss[4]); \
-}
-#define kd4(k,i) \
-{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] 
= ff(ss[4]); \
-    k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
-    k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
-}
-#define kdl4(k,i) \
-{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
-    k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; 
\
-    k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
-}
-#else
-#define kdf4(k,i) \
-{   ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= 
ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
-    ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = 
ff(ss[3]); \
-}
-#define kd4(k,i) \
-{   ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \
-    ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
-    ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
-    ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
-    ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
-}
-#define kdl4(k,i) \
-{   ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= 
ss[0]; k[4*(i)+ 5] = ss[1]; \
-    ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
-}
-#endif
-
-#define kdf6(k,i) \
-{   ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= 
ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
-    ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = 
ff(ss[3]); \
-    ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = 
ff(ss[5]); \
-}
-#define kd6(k,i) \
-{   ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \
-    ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
-    ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
-    ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
-    ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
-    ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
-    ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
-}
-#define kdl6(k,i) \
-{   ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= 
ss[0]; k[6*(i)+ 7] = ss[1]; \
-    ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
-}
-
-#define kdf8(k,i) \
-{   ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= 
ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
-    ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = 
ff(ss[3]); \
-    ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; 
k[8*(i)+13] = ff(ss[5]); \
-    ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = 
ff(ss[7]); \
-}
-#define kd8(k,i) \
-{   aes_32t g = ls_box(ss[7],3) ^ rcon_tab[i]; \
-    ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
-    ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
-    ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
-    ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
-    g = ls_box(ss[3],0); \
-    ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
-    ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
-    ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
-    ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
-}
-#define kdl8(k,i) \
-{   ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= 
ss[0]; k[8*(i)+ 9] = ss[1]; \
-    ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
-}
-
-aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1])
-{   aes_32t    ss[8]; 
-    d_vars
-
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-#if !defined(BLOCK_SIZE)
-    if(!cx->n_blk) cx->n_blk = 16;
-#else
-    cx->n_blk = BLOCK_SIZE;
-#endif
-
-    cx->n_blk = (cx->n_blk & ~3) | 2;
-
-    cx->k_sch[0] = ss[0] = word_in(in_key     );
-    cx->k_sch[1] = ss[1] = word_in(in_key +  4);
-    cx->k_sch[2] = ss[2] = word_in(in_key +  8);
-    cx->k_sch[3] = ss[3] = word_in(in_key + 12);
-
-#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE)
-
-    switch(klen)
-    {
-    case 16:    kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1); 
-                kd4(cx->k_sch, 2); kd4(cx->k_sch, 3);
-                kd4(cx->k_sch, 4); kd4(cx->k_sch, 5); 
-                kd4(cx->k_sch, 6); kd4(cx->k_sch, 7);
-                kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9); 
-                cx->n_rnd = 10; break;
-    case 24:    cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
-                cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
-                kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1); 
-                kd6(cx->k_sch, 2); kd6(cx->k_sch, 3);
-                kd6(cx->k_sch, 4); kd6(cx->k_sch, 5); 
-                kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7); 
-                cx->n_rnd = 12; break;
-    case 32:    cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
-                cx->k_sch[5] = ff(ss[5] = word_in(in_key + 20));
-                cx->k_sch[6] = ff(ss[6] = word_in(in_key + 24));
-                cx->k_sch[7] = ff(ss[7] = word_in(in_key + 28));
-                kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1); 
-                kd8(cx->k_sch, 2); kd8(cx->k_sch, 3);
-                kd8(cx->k_sch, 4); kd8(cx->k_sch, 5); 
-                kdl8(cx->k_sch, 6); 
-                cx->n_rnd = 14; break;
-    default:    cx->n_rnd = 0; return aes_bad; 
-    }
-#else
-    {   aes_32t i, l;
-        cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-        l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
-
-        switch(klen)
-        {
-        case 16: 
-                    for(i = 0; i < l; ++i)
-                        ke4(cx->k_sch, i);
-                    break;
-        case 24:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                    cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                    for(i = 0; i < l; ++i)
-                        ke6(cx->k_sch, i);
-                    break;
-        case 32:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                    cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                    cx->k_sch[6] = ss[6] = word_in(in_key + 24);
-                    cx->k_sch[7] = ss[7] = word_in(in_key + 28);
-                    for(i = 0; i < l; ++i)
-                        ke8(cx->k_sch,  i);
-                    break;
-        default:    cx->n_rnd = 0; return aes_bad; 
-        }
-#if (DEC_ROUND != NO_TABLES)
-        for(i = nc; i < nc * cx->n_rnd; ++i)
-            cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
-#endif
-    }
-#endif
-
-    return aes_good;
-}
-
-#endif
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ *    notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ *    built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ * -------------------------------------------------------------------------
+ * Issue Date: 29/07/2002
+ *
+ * This file contains the code for implementing the key schedule for AES
+ * (Rijndael) for block and key sizes of 16, 24, and 32 bytes.
+ */
+
+#include "aesopt.h"
+
+#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
+#error An illegal block size has been specified.
+#endif
+
+/* Subroutine to set the block size (if variable) in bytes, legal
+ * values being 16, 24 and 32.
+ */
+
+#if !defined(BLOCK_SIZE)
+
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
+{
+#if !defined(FIXED_TABLES)
+    if (!tab_init) {
+        gen_tabs();
+    }
+#endif
+
+    if ((blen & 7) || blen < 16 || blen > 32) {
+        cx->n_blk = 0;
+        return aes_bad;
+    }
+
+    cx->n_blk = blen;
+    return aes_good;
+}
+
+#endif
+
+/* Initialise the key schedule from the user supplied key. The key
+ * length is now specified in bytes - 16, 24 or 32 as appropriate.
+ * This corresponds to bit lengths of 128, 192 and 256 bits, and
+ * to Nk values of 4, 6 and 8 respectively.
+ *
+ * The following macros implement a single cycle in the key
+ * schedule generation process. The number of cycles needed
+ * for each cx->n_col and nk value is:
+ *
+ *  nk =             4  5  6  7  8
+ *  ------------------------------
+ *  cx->n_col = 4   10  9  8  7  7
+ *  cx->n_col = 5   14 11 10  9  9
+ *  cx->n_col = 6   19 15 12 11 11
+ *  cx->n_col = 7   21 19 16 13 14
+ *  cx->n_col = 8   29 23 19 17 14
+ */
+
+#define ke4(k, i) \
+    {   k[4 * (i) + 4] = ss[0] ^= ls_box(ss[3], 3) ^ rcon_tab[i]; k[4 * (i) + 
5] = ss[1] ^= ss[0]; \
+        k[4 * (i) + 6] = ss[2] ^= ss[1]; k[4 * (i) + 7] = ss[3] ^= ss[2]; \
+    }
+#define kel4(k, i) \
+    {   k[4 * (i) + 4] = ss[0] ^= ls_box(ss[3], 3) ^ rcon_tab[i]; k[4 * (i) + 
5] = ss[1] ^= ss[0]; \
+        k[4 * (i) + 6] = ss[2] ^= ss[1]; k[4 * (i) + 7] = ss[3] ^= ss[2]; \
+    }
+
+#define ke6(k, i) \
+    {   k[6 * (i) + 6]  = ss[0] ^= ls_box(ss[5], 3) ^ rcon_tab[i]; k[6 * (i) + 
7] = ss[1] ^= ss[0]; \
+        k[6 * (i) + 8]  = ss[2] ^= ss[1]; k[6 * (i) + 9] = ss[3] ^= ss[2]; \
+        k[6 * (i) + 10] = ss[4] ^= ss[3]; k[6 * (i) + 11] = ss[5] ^= ss[4]; \
+    }
+#define kel6(k, i) \
+    {   k[6 * (i) + 6] = ss[0] ^= ls_box(ss[5], 3) ^ rcon_tab[i]; k[6 * (i) + 
7] = ss[1] ^= ss[0]; \
+        k[6 * (i) + 8] = ss[2] ^= ss[1]; k[6 * (i) + 9] = ss[3] ^= ss[2]; \
+    }
+
+#define ke8(k, i) \
+    {   k[8 * (i) + 8]  = ss[0] ^= ls_box(ss[7], 3) ^ rcon_tab[i]; k[8 * (i) + 
9] = ss[1] ^= ss[0]; \
+        k[8 * (i) + 10] = ss[2] ^= ss[1]; k[8 * (i) + 11] = ss[3] ^= ss[2]; \
+        k[8 * (i) + 12] = ss[4] ^= ls_box(ss[3], 0); k[8 * (i) + 13] = ss[5] 
^= ss[4]; \
+        k[8 * (i) + 14] = ss[6] ^= ss[5]; k[8 * (i) + 15] = ss[7] ^= ss[6]; \
+    }
+#define kel8(k, i) \
+    {   k[8 * (i) + 8]  = ss[0] ^= ls_box(ss[7], 3) ^ rcon_tab[i]; k[8 * (i) + 
9] = ss[1] ^= ss[0]; \
+        k[8 * (i) + 10] = ss[2] ^= ss[1]; k[8 * (i) + 11] = ss[3] ^= ss[2]; \
+    }
+
+#if defined(ENCRYPTION_KEY_SCHEDULE)
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1])
+{
+    aes_32t ss[8];
+
+#if !defined(FIXED_TABLES)
+    if (!tab_init) {
+        gen_tabs();
+    }
+#endif
+
+#if !defined(BLOCK_SIZE)
+    if (!cx->n_blk) {
+        cx->n_blk = 16;
+    }
+#else
+    cx->n_blk    = BLOCK_SIZE;
+#endif
+
+    cx->n_blk    = (cx->n_blk & ~3) | 1;
+
+    cx->k_sch[0] = ss[0] = word_in(in_key     );
+    cx->k_sch[1] = ss[1] = word_in(in_key +  4);
+    cx->k_sch[2] = ss[2] = word_in(in_key +  8);
+    cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE)
+
+    switch (klen) {
+    case 16:    ke4(cx->k_sch, 0);
+        ke4(cx->k_sch, 1);
+        ke4(cx->k_sch, 2);
+        ke4(cx->k_sch, 3);
+        ke4(cx->k_sch, 4);
+        ke4(cx->k_sch, 5);
+        ke4(cx->k_sch, 6);
+        ke4(cx->k_sch, 7);
+        ke4(cx->k_sch, 8);
+        kel4(cx->k_sch, 9);
+        cx->n_rnd            = 10;
+        break;
+    case 24:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+        cx->k_sch[5]         = ss[5] = word_in(in_key + 20);
+        ke6(cx->k_sch, 0);
+        ke6(cx->k_sch, 1);
+        ke6(cx->k_sch, 2);
+        ke6(cx->k_sch, 3);
+        ke6(cx->k_sch, 4);
+        ke6(cx->k_sch, 5);
+        ke6(cx->k_sch, 6);
+        kel6(cx->k_sch, 7);
+        cx->n_rnd            = 12;
+        break;
+    case 32:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+        cx->k_sch[5]         = ss[5] = word_in(in_key + 20);
+        cx->k_sch[6]         = ss[6] = word_in(in_key + 24);
+        cx->k_sch[7]         = ss[7] = word_in(in_key + 28);
+        ke8(cx->k_sch, 0);
+        ke8(cx->k_sch, 1);
+        ke8(cx->k_sch, 2);
+        ke8(cx->k_sch, 3);
+        ke8(cx->k_sch, 4);
+        ke8(cx->k_sch, 5);
+        kel8(cx->k_sch, 6);
+        cx->n_rnd         = 14;
+        break;
+    default:    cx->n_rnd = 0;
+        return aes_bad;
+    }
+#else
+    {   aes_32t i, l;
+        cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+        l         = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
+
+        switch (klen) {
+        case 16:    for (i = 0; i < l; ++i) {
+                ke4(cx->k_sch, i);
+        }
+            break;
+        case 24:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+            cx->k_sch[5]         = ss[5] = word_in(in_key + 20);
+            for (i = 0; i < l; ++i) {
+                ke6(cx->k_sch, i);
+            }
+            break;
+        case 32:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+            cx->k_sch[5]         = ss[5] = word_in(in_key + 20);
+            cx->k_sch[6]         = ss[6] = word_in(in_key + 24);
+            cx->k_sch[7]         = ss[7] = word_in(in_key + 28);
+            for (i = 0; i < l; ++i) {
+                ke8(cx->k_sch,  i);
+            }
+            break;
+        default:    cx->n_rnd    = 0;
+            return aes_bad;
+        }
+    }
+#endif
+
+    return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION_KEY_SCHEDULE)
+
+#if (DEC_ROUND != NO_TABLES)
+#define d_vars  dec_imvars
+#define ff(x)   inv_mcol(x)
+#else
+#define ff(x)   (x)
+#define d_vars
+#endif
+
+#if 1
+#define kdf4(k, i) \
+    {   ss[0]  = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = 
ss[2] ^ ss[3]; ss[3] = ss[3]; \
+        ss[4]  = ls_box(ss[(i + 3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; 
\
+        ss[4] ^= k[4 * (i)];   k[4 * (i) + 4] = ff(ss[4]); ss[4] ^= k[4 * (i) 
+ 1]; k[4 * (i) + 5] = ff(ss[4]); \
+        ss[4] ^= k[4 * (i) + 2]; k[4 * (i) + 6] = ff(ss[4]); ss[4] ^= k[4 * 
(i) + 3]; k[4 * (i) + 7] = ff(ss[4]); \
+    }
+#define kd4(k, i) \
+    {   ss[4]          = ls_box(ss[(i + 3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] 
^= ss[4]; ss[4] = ff(ss[4]); \
+        k[4 * (i) + 4] = ss[4] ^= k[4 * (i)]; k[4 * (i) + 5] = ss[4] ^= k[4 * 
(i) + 1]; \
+        k[4 * (i) + 6] = ss[4] ^= k[4 * (i) + 2]; k[4 * (i) + 7] = ss[4] ^= 
k[4 * (i) + 3]; \
+    }
+#define kdl4(k, i) \
+    {   ss[4]                                              = ls_box(ss[(i + 3) 
% 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
+        k[4 * (i) + 4]                                     = (ss[0] ^= ss[1]) 
^ ss[2] ^ ss[3]; k[4 * (i) + 5] = ss[1] ^ ss[3]; \
+                                            k[4 * (i) + 6] = ss[0]; k[4 * (i) 
+ 7] = ss[1]; \
+                                            }
+#else
+#define kdf4(k, i) \
+    {   ss[0] ^= ls_box(ss[3], 3) ^ rcon_tab[i]; k[4 * (i) + 4] = ff(ss[0]); 
ss[1] ^= ss[0]; k[4 * (i) + 5] = ff(ss[1]); \
+        ss[2] ^= ss[1]; k[4 * (i) + 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4 * (i) 
+ 7] = ff(ss[3]); \
+    }
+#define kd4(k, i) \
+    {   ss[4]  = ls_box(ss[3], 3) ^ rcon_tab[i]; \
+        ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4 * (i) + 4] = ss[4] ^= k[4 * 
(i)]; \
+        ss[1] ^= ss[0]; k[4 * (i) + 5] = ss[4] ^= k[4 * (i) + 1]; \
+        ss[2] ^= ss[1]; k[4 * (i) + 6] = ss[4] ^= k[4 * (i) + 2]; \
+        ss[3] ^= ss[2]; k[4 * (i) + 7] = ss[4] ^= k[4 * (i) + 3]; \
+    }
+#define kdl4(k, i) \
+    {   ss[0] ^= ls_box(ss[3], 3) ^ rcon_tab[i]; k[4 * (i) + 4] = ss[0]; ss[1] 
^= ss[0]; k[4 * (i) + 5] = ss[1]; \
+        ss[2] ^= ss[1]; k[4 * (i) + 6] = ss[2]; ss[3] ^= ss[2]; k[4 * (i) + 7] 
= ss[3]; \
+    }
+#endif
+
+#define kdf6(k, i) \
+    {   ss[0] ^= ls_box(ss[5], 3) ^ rcon_tab[i]; k[6 * (i) + 6] = ff(ss[0]); 
ss[1] ^= ss[0]; k[6 * (i) + 7] = ff(ss[1]); \
+        ss[2] ^= ss[1]; k[6 * (i) + 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6 * (i) 
+ 9] = ff(ss[3]); \
+        ss[4] ^= ss[3]; k[6 * (i) + 10] = ff(ss[4]); ss[5] ^= ss[4]; k[6 * (i) 
+ 11] = ff(ss[5]); \
+    }
+#define kd6(k, i) \
+    {   ss[6]  = ls_box(ss[5], 3) ^ rcon_tab[i]; \
+        ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6 * (i) + 6] = ss[6] ^= k[6 * 
(i)]; \
+        ss[1] ^= ss[0]; k[6 * (i) + 7] = ss[6] ^= k[6 * (i) + 1]; \
+        ss[2] ^= ss[1]; k[6 * (i) + 8] = ss[6] ^= k[6 * (i) + 2]; \
+        ss[3] ^= ss[2]; k[6 * (i) + 9] = ss[6] ^= k[6 * (i) + 3]; \
+        ss[4] ^= ss[3]; k[6 * (i) + 10] = ss[6] ^= k[6 * (i) + 4]; \
+        ss[5] ^= ss[4]; k[6 * (i) + 11] = ss[6] ^= k[6 * (i) + 5]; \
+    }
+#define kdl6(k, i) \
+    {   ss[0] ^= ls_box(ss[5], 3) ^ rcon_tab[i]; k[6 * (i) + 6] = ss[0]; ss[1] 
^= ss[0]; k[6 * (i) + 7] = ss[1]; \
+        ss[2] ^= ss[1]; k[6 * (i) + 8] = ss[2]; ss[3] ^= ss[2]; k[6 * (i) + 9] 
= ss[3]; \
+    }
+
+#define kdf8(k, i) \
+    {   ss[0] ^= ls_box(ss[7], 3) ^ rcon_tab[i]; k[8 * (i) + 8] = ff(ss[0]); 
ss[1] ^= ss[0]; k[8 * (i) + 9] = ff(ss[1]); \
+        ss[2] ^= ss[1]; k[8 * (i) + 10] = ff(ss[2]); ss[3] ^= ss[2]; k[8 * (i) 
+ 11] = ff(ss[3]); \
+        ss[4] ^= ls_box(ss[3], 0); k[8 * (i) + 12] = ff(ss[4]); ss[5] ^= 
ss[4]; k[8 * (i) + 13] = ff(ss[5]); \
+        ss[6] ^= ss[5]; k[8 * (i) + 14] = ff(ss[6]); ss[7] ^= ss[6]; k[8 * (i) 
+ 15] = ff(ss[7]); \
+    }
+#define kd8(k, i) \
+    {   aes_32t g = ls_box(ss[7], 3) ^ rcon_tab[i]; \
+        ss[0] ^= g; g = ff(g); k[8 * (i) + 8] = g ^= k[8 * (i)]; \
+        ss[1] ^= ss[0]; k[8 * (i) + 9] = g ^= k[8 * (i) + 1]; \
+        ss[2] ^= ss[1]; k[8 * (i) + 10] = g ^= k[8 * (i) + 2]; \
+        ss[3] ^= ss[2]; k[8 * (i) + 11] = g ^= k[8 * (i) + 3]; \
+        g      = ls_box(ss[3], 0); \
+        ss[4] ^= g; g = ff(g); k[8 * (i) + 12] = g ^= k[8 * (i) + 4]; \
+        ss[5] ^= ss[4]; k[8 * (i) + 13] = g ^= k[8 * (i) + 5]; \
+        ss[6] ^= ss[5]; k[8 * (i) + 14] = g ^= k[8 * (i) + 6]; \
+        ss[7] ^= ss[6]; k[8 * (i) + 15] = g ^= k[8 * (i) + 7]; \
+    }
+#define kdl8(k, i) \
+    {   ss[0] ^= ls_box(ss[7], 3) ^ rcon_tab[i]; k[8 * (i) + 8] = ss[0]; ss[1] 
^= ss[0]; k[8 * (i) + 9] = ss[1]; \
+        ss[2] ^= ss[1]; k[8 * (i) + 10] = ss[2]; ss[3] ^= ss[2]; k[8 * (i) + 
11] = ss[3]; \
+    }
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1])
+{
+    aes_32t ss[8];
+    d_vars
+
+#if !defined(FIXED_TABLES)
+    if (!tab_init) {
+        gen_tabs();
+    }
+#endif
+
+#if !defined(BLOCK_SIZE)
+    if (!cx->n_blk) {
+        cx->n_blk = 16;
+    }
+#else
+    cx->n_blk    = BLOCK_SIZE;
+#endif
+
+    cx->n_blk    = (cx->n_blk & ~3) | 2;
+
+    cx->k_sch[0] = ss[0] = word_in(in_key     );
+    cx->k_sch[1] = ss[1] = word_in(in_key +  4);
+    cx->k_sch[2] = ss[2] = word_in(in_key +  8);
+    cx->k_sch[3] = ss[3] = word_in(in_key + 12);
+
+#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE)
+
+    switch (klen) {
+    case 16:    kdf4(cx->k_sch, 0);
+        kd4(cx->k_sch, 1);
+        kd4(cx->k_sch, 2);
+        kd4(cx->k_sch, 3);
+        kd4(cx->k_sch, 4);
+        kd4(cx->k_sch, 5);
+        kd4(cx->k_sch, 6);
+        kd4(cx->k_sch, 7);
+        kd4(cx->k_sch, 8);
+        kdl4(cx->k_sch, 9);
+        cx->n_rnd            = 10;
+        break;
+    case 24:    cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
+        cx->k_sch[5]         = ff(ss[5] = word_in(in_key + 20));
+        kdf6(cx->k_sch, 0);
+        kd6(cx->k_sch, 1);
+        kd6(cx->k_sch, 2);
+        kd6(cx->k_sch, 3);
+        kd6(cx->k_sch, 4);
+        kd6(cx->k_sch, 5);
+        kd6(cx->k_sch, 6);
+        kdl6(cx->k_sch, 7);
+        cx->n_rnd            = 12;
+        break;
+    case 32:    cx->k_sch[4] = ff(ss[4] = word_in(in_key + 16));
+        cx->k_sch[5]         = ff(ss[5] = word_in(in_key + 20));
+        cx->k_sch[6]         = ff(ss[6] = word_in(in_key + 24));
+        cx->k_sch[7]         = ff(ss[7] = word_in(in_key + 28));
+        kdf8(cx->k_sch, 0);
+        kd8(cx->k_sch, 1);
+        kd8(cx->k_sch, 2);
+        kd8(cx->k_sch, 3);
+        kd8(cx->k_sch, 4);
+        kd8(cx->k_sch, 5);
+        kdl8(cx->k_sch, 6);
+        cx->n_rnd         = 14;
+        break;
+    default:    cx->n_rnd = 0;
+        return aes_bad;
+    }
+#else
+    {   aes_32t i, l;
+        cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+        l         = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
+
+        switch (klen) {
+        case 16:
+            for (i = 0; i < l; ++i) {
+                ke4(cx->k_sch, i);
+            }
+            break;
+        case 24:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+            cx->k_sch[5]         = ss[5] = word_in(in_key + 20);
+            for (i = 0; i < l; ++i) {
+                ke6(cx->k_sch, i);
+            }
+            break;
+        case 32:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
+            cx->k_sch[5]         = ss[5] = word_in(in_key + 20);
+            cx->k_sch[6]         = ss[6] = word_in(in_key + 24);
+            cx->k_sch[7]         = ss[7] = word_in(in_key + 28);
+            for (i = 0; i < l; ++i) {
+                ke8(cx->k_sch,  i);
+            }
+            break;
+        default:    cx->n_rnd    = 0;
+            return aes_bad;
+        }
+#if (DEC_ROUND != NO_TABLES)
+        for (i = nc; i < nc * cx->n_rnd; ++i) {
+            cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
+        }
+#endif
+    }
+#endif
+
+    return aes_good;
+}
+
+#endif

=== modified file 'i3/aeshash/aeskeypp.c'
--- i3/aeshash/aeskeypp.c       2009-12-11 22:49:11 +0000
+++ i3/aeshash/aeskeypp.c       2010-02-11 11:49:47 +0000
@@ -1,399 +1,488 @@
-/*
- -------------------------------------------------------------------------
- Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary 
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright 
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products 
-      built using this software without specific written permission. 
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness 
- and fitness for purpose.
- -------------------------------------------------------------------------
- Issue Date: 29/07/2002
-
- This file contains the code for implementing the key schedule for AES 
- (Rijndael) for block and key sizes of 16, 20, 24, 28 and 32 bytes.
-*/
-
-#include "aesopt.h"
-
-/* Subroutine to set the block size (if variable) in bytes, legal
-   values being 16, 24 and 32. 
-*/
-
-#if !defined(BLOCK_SIZE)
-
-/* Subroutine to set the block size (if variable) in bytes, legal
-   values being 16, 24 and 32. 
-*/
-
-aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
-{
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-    if((blen & 3) || blen < 16 || blen > 32) 
-    {     
-        cx->n_blk = 0; return aes_bad;
-    }
-
-    cx->n_blk = blen;
-    return aes_good;
-}
-
-#endif
-
-/* Initialise the key schedule from the user supplied key. The key
-   length is now specified in bytes - 16, 24 or 32 as appropriate.
-   This corresponds to bit lengths of 128, 192 and 256 bits, and
-   to Nk values of 4, 6 and 8 respectively.
-
-   The following macros implement a single cycle in the key 
-   schedule generation process. The number of cycles needed 
-   for each cx->n_blk and nk value is:
- 
-    nk =             4  5  6  7  8
-    ------------------------------
-    cx->n_blk = 4   10  9  8  7  7
-    cx->n_blk = 5   14 11 10  9  9
-    cx->n_blk = 6   19 15 12 11 11
-    cx->n_blk = 7   21 19 16 13 14
-    cx->n_blk = 8   29 23 19 17 14
-*/
-
-/* Initialise the key schedule from the user supplied key. The key
-   length is now specified in bytes - 16, 20, 24, 28 or 32 as 
-   appropriate. This corresponds to bit lengths of 128, 160, 192,
-   224 and 256 bits, and to Nk values of 4, 5, 6, 7 & 8 respectively.
- */
-
-#define mx(t,f) (*t++ = inv_mcol(*f),f++)
-#define cp(t,f) *t++ = *f++
-
-#if   BLOCK_SIZE == 16
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-#elif BLOCK_SIZE == 20
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-                    cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-                    mx(d,s)
-#elif BLOCK_SIZE == 24
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-                    cp(d,s); cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-                    mx(d,s); mx(d,s)
-#elif BLOCK_SIZE == 28
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-                    cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-                    mx(d,s); mx(d,s); mx(d,s)
-#elif BLOCK_SIZE == 32
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-                    cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-                    mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-#else
-
-#define cpy(d,s) \
-switch(nc) \
-{   case 8: cp(d,s); \
-    case 7: cp(d,s); \
-    case 6: cp(d,s); \
-    case 5: cp(d,s); \
-    case 4: cp(d,s); cp(d,s); \
-            cp(d,s); cp(d,s); \
-}
-
-#define mix(d,s) \
-switch(nc) \
-{   case 8: mx(d,s); \
-    case 7: mx(d,s); \
-    case 6: mx(d,s); \
-    case 5: mx(d,s); \
-    case 4: mx(d,s); mx(d,s); \
-            mx(d,s); mx(d,s); \
-}
-
-#endif
-
-/*  The following macros implement a single cycle in the key 
-    schedule generation process. The number of cycles needed 
-    for each cx->n_blk and nk value is:
- 
-    nk =      4  5  6  7  8
-    -----------------------
-    cx->n_blk = 4   10  9  8  7  7
-    cx->n_blk = 5   14 11 10  9  9
-    cx->n_blk = 6   19 15 12 11 11
-    cx->n_blk = 7   21 19 16 13 14
-    cx->n_blk = 8   29 23 19 17 14
-*/
-
-#define ks4(i) \
-{   p ^= ls_box(s,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
-    cx->k_sch[4*(i)+4] = p; \
-    cx->k_sch[4*(i)+5] = q; \
-    cx->k_sch[4*(i)+6] = r; \
-    cx->k_sch[4*(i)+7] = s; \
-}
-
-#define ks5(i) \
-{   p ^= ls_box(t,3) ^ rcon_tab[i]; q ^= p; \
-    r ^= q; s ^= r; t ^= s; \
-    cx->k_sch[5*(i)+ 5] = p; \
-    cx->k_sch[5*(i)+ 6] = q; \
-    cx->k_sch[5*(i)+ 7] = r; \
-    cx->k_sch[5*(i)+ 8] = s; \
-    cx->k_sch[5*(i)+ 9] = t; \
-}
-
-#define ks6(i) \
-{   p ^= ls_box(u,3) ^ rcon_tab[i]; q ^= p; \
-    r ^= q; s ^= r; t ^= s; u ^= t; \
-    cx->k_sch[6*(i)+ 6] = p; \
-    cx->k_sch[6*(i)+ 7] = q; \
-    cx->k_sch[6*(i)+ 8] = r; \
-    cx->k_sch[6*(i)+ 9] = s; \
-    cx->k_sch[6*(i)+10] = t; \
-    cx->k_sch[6*(i)+11] = u; \
-}
-
-#define ks7(i) \
-{   p ^= ls_box(v,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
-    t ^= ls_box(s,0); u ^= t; v ^= u; \
-    cx->k_sch[7*(i)+ 7] = p; \
-    cx->k_sch[7*(i)+ 8] = q; \
-    cx->k_sch[7*(i)+ 9] = r; \
-    cx->k_sch[7*(i)+10] = s; \
-    cx->k_sch[7*(i)+11] = t; \
-    cx->k_sch[7*(i)+12] = u; \
-    cx->k_sch[7*(i)+13] = v; \
-}
-
-#define ks8(i) \
-{   p ^= ls_box(w,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
-    t ^= ls_box(s,0); u ^= t; v ^= u; w ^= v; \
-    cx->k_sch[8*(i)+ 8] = p; \
-    cx->k_sch[8*(i)+ 9] = q; \
-    cx->k_sch[8*(i)+10] = r; \
-    cx->k_sch[8*(i)+11] = s; \
-    cx->k_sch[8*(i)+12] = t; \
-    cx->k_sch[8*(i)+13] = u; \
-    cx->k_sch[8*(i)+14] = v; \
-    cx->k_sch[8*(i)+15] = w; \
-}
-
-#if defined(ENCRYPTION_KEY_SCHEDULE)
-
-aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1])
-{   aes_32t    i,p,q,r,s,t,u,v,w;
-
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-#if !defined(BLOCK_SIZE)
-    if(!cx->n_blk) cx->n_blk = 16;
-#else
-    cx->n_blk = BLOCK_SIZE;
-#endif
-
-    cx->n_blk = (cx->n_blk & ~3) | 1;
-    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-
-    cx->k_sch[0] = p = word_in(in_key     );
-    cx->k_sch[1] = q = word_in(in_key +  4);
-    cx->k_sch[2] = r = word_in(in_key +  8);
-    cx->k_sch[3] = s = word_in(in_key + 12);
-
-#if BLOCK_SIZE == 16 && defined(UNROLL)
-
-    switch(klen >> 2)
-    {
-    case 4: ks4(0); ks4(1); ks4(2); ks4(3);
-            ks4(4); ks4(5); ks4(6); ks4(7);
-            ks4(8); ks4(9); 
-            cx->n_rnd = 10; break;
-    case 5: cx->k_sch[4] = t = word_in(in_key + 16);
-            ks5(0); ks5(1); ks5(2); ks5(3);
-            ks5(4); ks5(5); ks5(6); ks5(7); 
-            ks5(8);  
-            cx->n_rnd = 11; break;
-    case 6: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            ks6(0); ks6(1); ks6(2); ks6(3);
-            ks6(4); ks6(5); ks6(6); ks6(7); 
-            cx->n_rnd = 12; break;
-    case 7: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            cx->k_sch[6] = v = word_in(in_key + 24);
-            ks7(0); ks7(1); ks7(2); ks7(3);
-            ks7(4); ks7(5); ks7(6); 
-            cx->n_rnd = 13; break;
-    case 8: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            cx->k_sch[6] = v = word_in(in_key + 24);
-            cx->k_sch[7] = w = word_in(in_key + 28);
-            ks8(0); ks8(1); ks8(2); ks8(3);
-            ks8(4); ks8(5); ks8(6); 
-            cx->n_rnd = 14; break;
-    default:cx->n_rnd = 0; return aes_bad;
-    }
-#else
-    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-    {
-        aes_32t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
-        switch(klen >> 2)
-        {
-        case 4: for(i = 0; i < l; ++i)
-                    ks4(i);
-                break;
-        case 5: cx->k_sch[4] = t = word_in(in_key + 16);
-                for(i = 0; i < l; ++i)
-                    ks5(i);
-                break;
-        case 6: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                for(i = 0; i < l; ++i)
-                    ks6(i);
-                break;
-        case 7: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                cx->k_sch[6] = v = word_in(in_key + 24);
-                for(i = 0; i < l; ++i)
-                    ks7(i);
-                break;
-        case 8: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                cx->k_sch[6] = v = word_in(in_key + 24);
-                cx->k_sch[7] = w = word_in(in_key + 28);
-                for(i = 0; i < l; ++i)
-                    ks8(i);
-                break;
-        }
-    }
-#endif
-
-    return aes_good;
-}
-
-#endif
-
-#if defined(DECRYPTION_KEY_SCHEDULE)
-
-aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1])
-{   aes_32t    i,p,q,r,s,t,u,v,w;
-    dec_imvars
-
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-#if !defined(BLOCK_SIZE)
-    if(!cx->n_blk) cx->n_blk = 16;
-#else
-    cx->n_blk = BLOCK_SIZE;
-#endif
-
-    cx->n_blk = (cx->n_blk & ~3) | 2;
-    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-
-    cx->k_sch[0] = p = word_in(in_key     );
-    cx->k_sch[1] = q = word_in(in_key +  4);
-    cx->k_sch[2] = r = word_in(in_key +  8);
-    cx->k_sch[3] = s = word_in(in_key + 12);
-
-#if BLOCK_SIZE == 16 && defined(UNROLL)
-
-    switch(klen >> 2)
-    {
-    case 4: ks4(0); ks4(1); ks4(2); ks4(3);
-            ks4(4); ks4(5); ks4(6); ks4(7);
-            ks4(8); ks4(9); 
-            cx->n_rnd = 10; break;
-    case 5: cx->k_sch[4] = t = word_in(in_key + 16);
-            ks5(0); ks5(1); ks5(2); ks5(3);
-            ks5(4); ks5(5); ks5(6); ks5(7); 
-            ks5(8);  
-            cx->n_rnd = 11; break;
-    case 6: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            ks6(0); ks6(1); ks6(2); ks6(3);
-            ks6(4); ks6(5); ks6(6); ks6(7); 
-            cx->n_rnd = 12; break;
-    case 7: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            cx->k_sch[6] = v = word_in(in_key + 24);
-            ks7(0); ks7(1); ks7(2); ks7(3);
-            ks7(4); ks7(5); ks7(6); 
-            cx->n_rnd = 13; break;
-    case 8: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            cx->k_sch[6] = v = word_in(in_key + 24);
-            cx->k_sch[7] = w = word_in(in_key + 28);
-            ks8(0); ks8(1); ks8(2); ks8(3);
-            ks8(4); ks8(5); ks8(6); 
-            cx->n_rnd = 14; break;
-    default:cx->n_rnd = 0; return aes_bad;
-    }
-#else
-    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-    {
-        aes_32t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
-        switch(klen >> 2)
-        {
-        case 4: for(i = 0; i < l; ++i)
-                    ks4(i);
-                break;
-        case 5: cx->k_sch[4] = t = word_in(in_key + 16);
-                for(i = 0; i < l; ++i)
-                    ks5(i);
-                break;
-        case 6: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                for(i = 0; i < l; ++i)
-                    ks6(i);
-                break;
-        case 7: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                cx->k_sch[6] = v = word_in(in_key + 24);
-                for(i = 0; i < l; ++i)
-                    ks7(i);
-                break;
-        case 8: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                cx->k_sch[6] = v = word_in(in_key + 24);
-                cx->k_sch[7] = w = word_in(in_key + 28);
-                for(i = 0; i < l; ++i)
-                    ks8(i);
-                break;
-        }
-    }
-#endif
-
-#if (DEC_ROUND != NO_TABLES)
-    for(i = nc; i < nc * cx->n_rnd; ++i)
-        cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
-#endif
-
-    return aes_good;
-}
-
-#endif
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ *    notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ *    built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ * -------------------------------------------------------------------------
+ * Issue Date: 29/07/2002
+ *
+ * This file contains the code for implementing the key schedule for AES
+ * (Rijndael) for block and key sizes of 16, 20, 24, 28 and 32 bytes.
+ */
+
+#include "aesopt.h"
+
+/* Subroutine to set the block size (if variable) in bytes, legal
+ * values being 16, 24 and 32.
+ */
+
+#if !defined(BLOCK_SIZE)
+
+/* Subroutine to set the block size (if variable) in bytes, legal
+ * values being 16, 24 and 32.
+ */
+
+aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
+{
+#if !defined(FIXED_TABLES)
+    if (!tab_init) {
+        gen_tabs();
+    }
+#endif
+
+    if ((blen & 3) || blen < 16 || blen > 32) {
+        cx->n_blk = 0;
+        return aes_bad;
+    }
+
+    cx->n_blk = blen;
+    return aes_good;
+}
+
+#endif
+
+/* Initialise the key schedule from the user supplied key. The key
+ * length is now specified in bytes - 16, 24 or 32 as appropriate.
+ * This corresponds to bit lengths of 128, 192 and 256 bits, and
+ * to Nk values of 4, 6 and 8 respectively.
+ *
+ * The following macros implement a single cycle in the key
+ * schedule generation process. The number of cycles needed
+ * for each cx->n_blk and nk value is:
+ *
+ *  nk =             4  5  6  7  8
+ *  ------------------------------
+ *  cx->n_blk = 4   10  9  8  7  7
+ *  cx->n_blk = 5   14 11 10  9  9
+ *  cx->n_blk = 6   19 15 12 11 11
+ *  cx->n_blk = 7   21 19 16 13 14
+ *  cx->n_blk = 8   29 23 19 17 14
+ */
+
+/* Initialise the key schedule from the user supplied key. The key
+ * length is now specified in bytes - 16, 20, 24, 28 or 32 as
+ * appropriate. This corresponds to bit lengths of 128, 160, 192,
+ * 224 and 256 bits, and to Nk values of 4, 5, 6, 7 & 8 respectively.
+ */
+
+#define mx(t, f) (*t++ = inv_mcol(*f), f++)
+#define cp(t, f) *t++ = *f++
+
+#if   BLOCK_SIZE == 16
+#define cpy(d, s)    cp(d, s); cp(d, s); cp(d, s); cp(d, s)
+#define mix(d, s)    mx(d, s); mx(d, s); mx(d, s); mx(d, s)
+#elif BLOCK_SIZE == 20
+#define cpy(d, s)    cp(d, s); cp(d, s); cp(d, s); cp(d, s); \
+    cp(d, s)
+#define mix(d, s)    mx(d, s); mx(d, s); mx(d, s); mx(d, s); \
+    mx(d, s)
+#elif BLOCK_SIZE == 24
+#define cpy(d, s)    cp(d, s); cp(d, s); cp(d, s); cp(d, s); \
+    cp(d, s); cp(d, s)
+#define mix(d, s)    mx(d, s); mx(d, s); mx(d, s); mx(d, s); \
+    mx(d, s); mx(d, s)
+#elif BLOCK_SIZE == 28
+#define cpy(d, s)    cp(d, s); cp(d, s); cp(d, s); cp(d, s); \
+    cp(d, s); cp(d, s); cp(d, s)
+#define mix(d, s)    mx(d, s); mx(d, s); mx(d, s); mx(d, s); \
+    mx(d, s); mx(d, s); mx(d, s)
+#elif BLOCK_SIZE == 32
+#define cpy(d, s)    cp(d, s); cp(d, s); cp(d, s); cp(d, s); \
+    cp(d, s); cp(d, s); cp(d, s); cp(d, s)
+#define mix(d, s)    mx(d, s); mx(d, s); mx(d, s); mx(d, s); \
+    mx(d, s); mx(d, s); mx(d, s); mx(d, s)
+#else
+
+#define cpy(d, s) \
+    switch (nc) \
+    {   case 8: cp(d, s); \
+    case 7: cp(d, s); \
+    case 6: cp(d, s); \
+    case 5: cp(d, s); \
+    case 4: cp(d, s); cp(d, s); \
+        cp(d, s); cp(d, s); \
+    }
+
+#define mix(d, s) \
+    switch (nc) \
+    {   case 8: mx(d, s); \
+    case 7: mx(d, s); \
+    case 6: mx(d, s); \
+    case 5: mx(d, s); \
+    case 4: mx(d, s); mx(d, s); \
+        mx(d, s); mx(d, s); \
+    }
+
+#endif
+
+/*  The following macros implement a single cycle in the key
+ *  schedule generation process. The number of cycles needed
+ *  for each cx->n_blk and nk value is:
+ *
+ *  nk =      4  5  6  7  8
+ *  -----------------------
+ *  cx->n_blk = 4   10  9  8  7  7
+ *  cx->n_blk = 5   14 11 10  9  9
+ *  cx->n_blk = 6   19 15 12 11 11
+ *  cx->n_blk = 7   21 19 16 13 14
+ *  cx->n_blk = 8   29 23 19 17 14
+ */
+
+#define ks4(i) \
+    {   p                     ^= ls_box(s, 3) ^ rcon_tab[i]; q ^= p; r ^= q; s 
^= r; \
+        cx->k_sch[4 * (i) + 4] = p; \
+        cx->k_sch[4 * (i) + 5] = q; \
+        cx->k_sch[4 * (i) + 6] = r; \
+        cx->k_sch[4 * (i) + 7] = s; \
+    }
+
+#define ks5(i) \
+    {   p                     ^= ls_box(t, 3) ^ rcon_tab[i]; q ^= p; \
+        r                     ^= q; s ^= r; t ^= s; \
+        cx->k_sch[5 * (i) + 5] = p; \
+        cx->k_sch[5 * (i) + 6] = q; \
+        cx->k_sch[5 * (i) + 7] = r; \
+        cx->k_sch[5 * (i) + 8] = s; \
+        cx->k_sch[5 * (i) + 9] = t; \
+    }
+
+#define ks6(i) \
+    {   p                      ^= ls_box(u, 3) ^ rcon_tab[i]; q ^= p; \
+        r                      ^= q; s ^= r; t ^= s; u ^= t; \
+        cx->k_sch[6 * (i) + 6]  = p; \
+        cx->k_sch[6 * (i) + 7]  = q; \
+        cx->k_sch[6 * (i) + 8]  = r; \
+        cx->k_sch[6 * (i) + 9]  = s; \
+        cx->k_sch[6 * (i) + 10] = t; \
+        cx->k_sch[6 * (i) + 11] = u; \
+    }
+
+#define ks7(i) \
+    {   p                      ^= ls_box(v, 3) ^ rcon_tab[i]; q ^= p; r ^= q; 
s ^= r; \
+        t                      ^= ls_box(s, 0); u ^= t; v ^= u; \
+        cx->k_sch[7 * (i) + 7]  = p; \
+        cx->k_sch[7 * (i) + 8]  = q; \
+        cx->k_sch[7 * (i) + 9]  = r; \
+        cx->k_sch[7 * (i) + 10] = s; \
+        cx->k_sch[7 * (i) + 11] = t; \
+        cx->k_sch[7 * (i) + 12] = u; \
+        cx->k_sch[7 * (i) + 13] = v; \
+    }
+
+#define ks8(i) \
+    {   p                      ^= ls_box(w, 3) ^ rcon_tab[i]; q ^= p; r ^= q; 
s ^= r; \
+        t                      ^= ls_box(s, 0); u ^= t; v ^= u; w ^= v; \
+        cx->k_sch[8 * (i) + 8]  = p; \
+        cx->k_sch[8 * (i) + 9]  = q; \
+        cx->k_sch[8 * (i) + 10] = r; \
+        cx->k_sch[8 * (i) + 11] = s; \
+        cx->k_sch[8 * (i) + 12] = t; \
+        cx->k_sch[8 * (i) + 13] = u; \
+        cx->k_sch[8 * (i) + 14] = v; \
+        cx->k_sch[8 * (i) + 15] = w; \
+    }
+
+#if defined(ENCRYPTION_KEY_SCHEDULE)
+
+aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1])
+{
+    aes_32t i, p, q, r, s, t, u, v, w;
+
+#if !defined(FIXED_TABLES)
+    if (!tab_init) {
+        gen_tabs();
+    }
+#endif
+
+#if !defined(BLOCK_SIZE)
+    if (!cx->n_blk) {
+        cx->n_blk = 16;
+    }
+#else
+    cx->n_blk    = BLOCK_SIZE;
+#endif
+
+    cx->n_blk    = (cx->n_blk & ~3) | 1;
+    cx->n_rnd    = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+
+    cx->k_sch[0] = p = word_in(in_key     );
+    cx->k_sch[1] = q = word_in(in_key +  4);
+    cx->k_sch[2] = r = word_in(in_key +  8);
+    cx->k_sch[3] = s = word_in(in_key + 12);
+
+#if BLOCK_SIZE == 16 && defined(UNROLL)
+
+    switch (klen >> 2) {
+    case 4: ks4(0);
+        ks4(1);
+        ks4(2);
+        ks4(3);
+        ks4(4);
+        ks4(5);
+        ks4(6);
+        ks4(7);
+        ks4(8);
+        ks4(9);
+        cx->n_rnd        = 10;
+        break;
+    case 5: cx->k_sch[4] = t = word_in(in_key + 16);
+        ks5(0);
+        ks5(1);
+        ks5(2);
+        ks5(3);
+        ks5(4);
+        ks5(5);
+        ks5(6);
+        ks5(7);
+        ks5(8);
+        cx->n_rnd        = 11;
+        break;
+    case 6: cx->k_sch[4] = t = word_in(in_key + 16);
+        cx->k_sch[5]     = u = word_in(in_key + 20);
+        ks6(0);
+        ks6(1);
+        ks6(2);
+        ks6(3);
+        ks6(4);
+        ks6(5);
+        ks6(6);
+        ks6(7);
+        cx->n_rnd        = 12;
+        break;
+    case 7: cx->k_sch[4] = t = word_in(in_key + 16);
+        cx->k_sch[5]     = u = word_in(in_key + 20);
+        cx->k_sch[6]     = v = word_in(in_key + 24);
+        ks7(0);
+        ks7(1);
+        ks7(2);
+        ks7(3);
+        ks7(4);
+        ks7(5);
+        ks7(6);
+        cx->n_rnd        = 13;
+        break;
+    case 8: cx->k_sch[4] = t = word_in(in_key + 16);
+        cx->k_sch[5]     = u = word_in(in_key + 20);
+        cx->k_sch[6]     = v = word_in(in_key + 24);
+        cx->k_sch[7]     = w = word_in(in_key + 28);
+        ks8(0);
+        ks8(1);
+        ks8(2);
+        ks8(3);
+        ks8(4);
+        ks8(5);
+        ks8(6);
+        cx->n_rnd      = 14;
+        break;
+    default: cx->n_rnd = 0;
+        return aes_bad;
+    }
+#else
+    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+    {
+        aes_32t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
+        switch (klen >> 2) {
+        case 4: for (i = 0; i < l; ++i) {
+                ks4(i);
+        }
+            break;
+        case 5: cx->k_sch[4] = t = word_in(in_key + 16);
+            for (i = 0; i < l; ++i) {
+                ks5(i);
+            }
+            break;
+        case 6: cx->k_sch[4] = t = word_in(in_key + 16);
+            cx->k_sch[5]     = u = word_in(in_key + 20);
+            for (i = 0; i < l; ++i) {
+                ks6(i);
+            }
+            break;
+        case 7: cx->k_sch[4] = t = word_in(in_key + 16);
+            cx->k_sch[5]     = u = word_in(in_key + 20);
+            cx->k_sch[6]     = v = word_in(in_key + 24);
+            for (i = 0; i < l; ++i) {
+                ks7(i);
+            }
+            break;
+        case 8: cx->k_sch[4] = t = word_in(in_key + 16);
+            cx->k_sch[5]     = u = word_in(in_key + 20);
+            cx->k_sch[6]     = v = word_in(in_key + 24);
+            cx->k_sch[7]     = w = word_in(in_key + 28);
+            for (i = 0; i < l; ++i) {
+                ks8(i);
+            }
+            break;
+        }
+    }
+#endif
+
+    return aes_good;
+}
+
+#endif
+
+#if defined(DECRYPTION_KEY_SCHEDULE)
+
+aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx 
cx[1])
+{
+    aes_32t i, p, q, r, s, t, u, v, w;
+    dec_imvars
+
+#if !defined(FIXED_TABLES)
+    if (!tab_init) {
+        gen_tabs();
+    }
+#endif
+
+#if !defined(BLOCK_SIZE)
+    if (!cx->n_blk) {
+        cx->n_blk = 16;
+    }
+#else
+    cx->n_blk    = BLOCK_SIZE;
+#endif
+
+    cx->n_blk    = (cx->n_blk & ~3) | 2;
+    cx->n_rnd    = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+
+    cx->k_sch[0] = p = word_in(in_key     );
+    cx->k_sch[1] = q = word_in(in_key +  4);
+    cx->k_sch[2] = r = word_in(in_key +  8);
+    cx->k_sch[3] = s = word_in(in_key + 12);
+
+#if BLOCK_SIZE == 16 && defined(UNROLL)
+
+    switch (klen >> 2) {
+    case 4: ks4(0);
+        ks4(1);
+        ks4(2);
+        ks4(3);
+        ks4(4);
+        ks4(5);
+        ks4(6);
+        ks4(7);
+        ks4(8);
+        ks4(9);
+        cx->n_rnd        = 10;
+        break;
+    case 5: cx->k_sch[4] = t = word_in(in_key + 16);
+        ks5(0);
+        ks5(1);
+        ks5(2);
+        ks5(3);
+        ks5(4);
+        ks5(5);
+        ks5(6);
+        ks5(7);
+        ks5(8);
+        cx->n_rnd        = 11;
+        break;
+    case 6: cx->k_sch[4] = t = word_in(in_key + 16);
+        cx->k_sch[5]     = u = word_in(in_key + 20);
+        ks6(0);
+        ks6(1);
+        ks6(2);
+        ks6(3);
+        ks6(4);
+        ks6(5);
+        ks6(6);
+        ks6(7);
+        cx->n_rnd        = 12;
+        break;
+    case 7: cx->k_sch[4] = t = word_in(in_key + 16);
+        cx->k_sch[5]     = u = word_in(in_key + 20);
+        cx->k_sch[6]     = v = word_in(in_key + 24);
+        ks7(0);
+        ks7(1);
+        ks7(2);
+        ks7(3);
+        ks7(4);
+        ks7(5);
+        ks7(6);
+        cx->n_rnd        = 13;
+        break;
+    case 8: cx->k_sch[4] = t = word_in(in_key + 16);
+        cx->k_sch[5]     = u = word_in(in_key + 20);
+        cx->k_sch[6]     = v = word_in(in_key + 24);
+        cx->k_sch[7]     = w = word_in(in_key + 28);
+        ks8(0);
+        ks8(1);
+        ks8(2);
+        ks8(3);
+        ks8(4);
+        ks8(5);
+        ks8(6);
+        cx->n_rnd      = 14;
+        break;
+    default: cx->n_rnd = 0;
+        return aes_bad;
+    }
+#else
+    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
+    {
+        aes_32t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
+        switch (klen >> 2) {
+        case 4: for (i = 0; i < l; ++i) {
+                ks4(i);
+        }
+            break;
+        case 5: cx->k_sch[4] = t = word_in(in_key + 16);
+            for (i = 0; i < l; ++i) {
+                ks5(i);
+            }
+            break;
+        case 6: cx->k_sch[4] = t = word_in(in_key + 16);
+            cx->k_sch[5]     = u = word_in(in_key + 20);
+            for (i = 0; i < l; ++i) {
+                ks6(i);
+            }
+            break;
+        case 7: cx->k_sch[4] = t = word_in(in_key + 16);
+            cx->k_sch[5]     = u = word_in(in_key + 20);
+            cx->k_sch[6]     = v = word_in(in_key + 24);
+            for (i = 0; i < l; ++i) {
+                ks7(i);
+            }
+            break;
+        case 8: cx->k_sch[4] = t = word_in(in_key + 16);
+            cx->k_sch[5]     = u = word_in(in_key + 20);
+            cx->k_sch[6]     = v = word_in(in_key + 24);
+            cx->k_sch[7]     = w = word_in(in_key + 28);
+            for (i = 0; i < l; ++i) {
+                ks8(i);
+            }
+            break;
+        }
+    }
+#endif
+
+#if (DEC_ROUND != NO_TABLES)
+    for (i = nc; i < nc * cx->n_rnd; ++i) {
+        cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
+    }
+#endif
+
+    return aes_good;
+}
+
+#endif

=== modified file 'i3/aeshash/aesopt.h'
--- i3/aeshash/aesopt.h 2010-02-10 00:01:34 +0000
+++ i3/aeshash/aesopt.h 2010-02-11 11:49:47 +0000
@@ -1,841 +1,841 @@
-/*
- -------------------------------------------------------------------------
- Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary 
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright 
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products 
-      built using this software without specific written permission. 
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness 
- and fitness for purpose.
- -------------------------------------------------------------------------
- Issue Date: 29/07/2002
-
- This file contains the compilation options for AES (Rijndael) and code 
- that is common across encryption, key scheduling and table generation.
-
-    OPERATION
- 
-    These source code files implement the AES algorithm Rijndael designed by
-    Joan Daemen and Vincent Rijmen. The version in aes.c is designed for 
-    block and key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes) while 
-    that in aespp.c provides for block and keys sizes of 128, 160, 192, 224 
-    and 256 bits (16, 20, 24, 28 and 32 bytes).  This file is a common header 
-    file for these two implementations and for aesref.c, which is a reference 
-    implementation.
-    
-    This version is designed for flexibility and speed using operations on
-    32-bit words rather than operations on bytes.  It provides aes_both fixed 
-    and  dynamic block and key lengths and can also run with either big or 
-    little endian internal byte order (see aes.h).  It inputs block and key 
-    lengths in bytes with the legal values being  16, 24 and 32 for aes.c and 
-    16, 20, 24, 28 and 32 for aespp.c
- 
-    THE CIPHER INTERFACE
-
-    aes_08t         (an unsigned  8-bit type)
-    aes_32t         (an unsigned 32-bit type)
-    aes_fret        (a signed 16 bit type for function return values)
-    aes_good        (value != 0, a good return)
-    aes_bad         (value == 0, an error return)
-    struct aes_ctx  (structure for the cipher encryption context)
-    struct aes_ctx  (structure for the cipher decryption context)
-    aes_rval        the function return type (aes_fret if not DLL)
-
-    C subroutine calls:
-
-      aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
-      aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, 
aes_ctx cx[1]);
-      aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char 
out_blk[], const aes_ctx cx[1]);
-
-      aes_rval aes_dec_len(unsigned int blen, aes_ctx cx[1]);
-      aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, 
aes_ctx cx[1]);
-      aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char 
out_blk[], const aes_ctx cx[1]);
-
-    IMPORTANT NOTE: If you are using this C interface and your compiler does 
-    not set the memory used for objects to zero before use, you will need to 
-    ensure that cx.s_flg is set to zero before using these subroutine calls.
-
-    C++ aes class subroutines:
-
-      class AESclass    for encryption
-      class AESclass    for decryption
-
-      aes_rval len(unsigned int blen = 16);
-      aes_rval key(const unsigned char in_key[], unsigned int klen);
-      aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
-
-      aes_rval len(unsigned int blen = 16);
-      aes_rval key(const unsigned char in_key[], unsigned int klen);
-      aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
-
-    The block length inputs to set_block and set_key are in numbers of
-    BYTES, not bits.  The calls to subroutines must be made in the above 
-    order but multiple calls can be made without repeating earlier calls
-    if their parameters have not changed. If the cipher block length is
-    variable but set_blk has not been called before cipher operations a
-    value of 16 is assumed (that is, the AES block size). In contrast to 
-    earlier versions the block and key length parameters are now checked
-    for correctness and the encryption and decryption routines check to 
-    ensure that an appropriate key has been set before they are called.
-
-    COMPILATION 
-
-    The files used to provide AES (Rijndael) are
-
-    a. aes.h for the definitions needed for use in C.
-    b. aescpp.h for the definitions needed for use in C++. 
-    c. aesopt.h for setting compilation options (also includes common
-       code).
-    d. aescrypt.c for encryption and decrytpion, or
-    e. aescrypt.asm for encryption and decryption using assembler code.
-    f. aeskey.c for key scheduling.
-    g. aestab.c for table loading or generation.
-
-    The assembler code uses the NASM assembler. The above files provice
-    block and key lengths of 16, 24 and 32 bytes (128, 192 and 256 bits).
-    If aescrypp.c and aeskeypp.c are used instead of aescrypt.c and
-    aeskey.c respectively, the block and key lengths can then be 16, 20,
-    24, 28 or 32 bytes. However this code has not been optimised to the 
-    same extent and is hence slower (esepcially for the AES block size
-    of 16 bytes).
-
-    To compile AES (Rijndael) for use in C code use aes.h and exclude
-    the AES_DLL define in aes.h
-
-    To compile AES (Rijndael) for use in in C++ code use aescpp.h and
-    exclude the AES_DLL define in aes.h
-
-    To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
-    aes.h, include the AES_DLL define and compile the DLL.  If using 
-    the test files to test the DLL, exclude aes.c from the test build
-    project and compile it with the same defines as used for the DLL 
-    (ensure that the DLL path is correct)
-
-    CONFIGURATION OPTIONS (here and in aes.h)
-
-    a. define BLOCK_SIZE in aes.h to set the cipher block size (16, 24 
-       or 32 for the standard code, or 16, 20, 24, 28 or 32 for the 
-       extended code) or leave this undefined for dynamically variable 
-       block size (this will result in much slower code).
-    b. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
-    c. You may need to set PLATFORM_BYTE_ORDER to define the byte order. 
-    d. If you want the code to run in a specific internal byte order, then
-       INTERNAL_BYTE_ORDER must be set accordingly.
-    e. set other configuration options decribed below.
-*/ 
-
-#ifndef _AESOPT_H
-#define _AESOPT_H
-
-/*  START OF CONFIGURATION OPTIONS
-
-    USE OF DEFINES
-  
-    Later in this section there are a number of defines that control the 
-    operation of the code.  In each section, the purpose of each define is 
-    explained so that the relevant form can be included or excluded by 
-    setting either 1's or 0's respectively on the branches of the related 
-    #if clauses.
-*/
-
-/*  1. PLATFORM SPECIFIC INCLUDES */
-
-#if defined( __CRYPTLIB__ ) && !defined( INC_ALL ) && !defined( INC_CHILD )
-#include "crypt/aes.h"
-#else
-  #include "aes.h"
-#endif
-
-#if (defined(__GNUC__) || defined(__GNU_LIBRARY__)) && !defined(__CYGWIN__)
-#  if defined(__APPLE__)
-#    include <machine/endian.h>
-#  else
-#    include <endian.h>
-#  endif
-//#  include <machine/byteswap.h>
-#elif defined(__CRYPTLIB__)
-#  if defined( INC_ALL )
-#    include "crypt.h"
-#  elif defined( INC_CHILD )
-#    include "../crypt.h"
-#  else
-#    include "crypt.h"
-#  endif
-#  if defined(DATA_LITTLEENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#  else
-#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#  endif
-#elif defined(_MSC_VER)
-#  include <stdlib.h>
-#elif !defined(WIN32)
-#  include <stdlib.h>
-#  if !defined (_ENDIAN_H)
-#    include <sys/param.h>
-#  else
-#    include _ENDIAN_H
-#  endif
-#endif
-
-/*  2. BYTE ORDER IN 32-BIT WORDS
-
-    To obtain the highest speed on processors with 32-bit words, this code 
-    needs to determine the order in which bytes are packed into such words.
-    The following block of code is an attempt to capture the most obvious 
-    ways in which various environemnts define byte order. It may well fail, 
-    in which case the definitions will need to be set by editing at the 
-    points marked **** EDIT HERE IF NECESSARY **** below.
-*/
-#define AES_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
-#define AES_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
-
-#if !defined(PLATFORM_BYTE_ORDER)
-#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
-#  if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
-#    if defined(BYTE_ORDER)
-#      if   (BYTE_ORDER == LITTLE_ENDIAN)
-#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#      elif (BYTE_ORDER == BIG_ENDIAN)
-#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#      endif
-#    endif
-#  elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) 
-#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#  elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#  endif
-#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
-#  if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
-#    if defined(_BYTE_ORDER)
-#      if   (_BYTE_ORDER == _LITTLE_ENDIAN)
-#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#      elif (_BYTE_ORDER == _BIG_ENDIAN)
-#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#      endif
-#    endif
-#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) 
-#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#  elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#  endif
-#elif defined(__BYTE_ORDER)
-#  if   (__BYTE_ORDER == __LITTLE_ENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#  elif (__BYTE_ORDER == __BIG_ENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#  endif
-#elif 0     /* **** EDIT HERE IF NECESSARY **** */
-#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#elif 1     /* **** EDIT HERE IF NECESSARY **** */
-XX_FIXME
-/*#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#elif (('1234' >> 24) == '1')
-#  define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#elif (('4321' >> 24) == '1')
-#  define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN */
-#endif
-#endif
-
-#if !defined(PLATFORM_BYTE_ORDER)
-#  error Please set undetermined byte order (lines 233 or 235 of aesopt.h).
-#endif
-
-/*  3. ASSEMBLER SUPPORT
-    
-    If the assembler code is used for encryption and decryption this file only 
-    provides key scheduling so the following defines are used
-*/
-#ifdef  AES_ASM
-#define ENCRYPTION_KEY_SCHEDULE
-#define DECRYPTION_KEY_SCHEDULE
-#else
-
-/*  4. FUNCTIONS REQUIRED
-
-    This implementation provides five main subroutines which provide for
-    setting block length, setting encryption and decryption keys and for
-    encryption and decryption. When the assembler code is not being used
-    the following definition blocks allow the selection of the routines
-    that are to be included in the compilation.
-*/
-#if 1
-#define ENCRYPTION_KEY_SCHEDULE
-#endif
-
-#if 1
-#define DECRYPTION_KEY_SCHEDULE
-#endif
-
-#if 1
-#define ENCRYPTION
-#endif
-
-#if 1
-#define DECRYPTION
-#endif
-
-#endif
-
-/*  5. BYTE ORDER WITHIN 32 BIT WORDS
-
-    The fundamental data processing units in Rijndael are 8-bit bytes. The 
-    input, output and key input are all enumerated arrays of bytes in which 
-    bytes are numbered starting at zero and increasing to one less than the 
-    number of bytes in the array in question. This enumeration is only used 
-    for naming bytes and does not imply any adjacency or order relationship 
-    from one byte to another. When these inputs and outputs are considered 
-    as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to 
-    byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte. 
-    In this implementation bits are numbered from 0 to 7 starting at the 
-    numerically least significant end of each byte (bit n represents 2^n).
-
-    However, Rijndael can be implemented more efficiently using 32-bit 
-    words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
-    into word[n]. While in principle these bytes can be assembled into words 
-    in any positions, this implementation only supports the two formats in 
-    which bytes in adjacent positions within words also have adjacent byte
-    numbers. This order is called big-endian if the lowest numbered bytes 
-    in words have the highest numeric significance and little-endian if the 
-    opposite applies. 
-    
-    This code can work in either order irrespective of the order used by the 
-    machine on which it runs. Normally the internal byte order will be set
-    to the order of the processor on which the code is to be run but this
-    define can be used to reverse this in special situations
-*/
-#if 1
-#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
-#elif defined(AES_LITTLE_ENDIAN)
-#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
-#elif defined(AES_BIG_ENDIAN)
-#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
-#endif
-
-/*  6. FAST INPUT/OUTPUT OPERATIONS.  
-
-    On some machines it is possible to improve speed by transferring the 
-    bytes in the input and output arrays to and from the internal 32-bit 
-    variables by addressing these arrays as if they are arrays of 32-bit 
-    words.  On some machines this will always be possible but there may 
-    be a large performance penalty if the byte arrays are not aligned on 
-    the normal word boundaries. On other machines this technique will 
-    lead to memory access errors when such 32-bit word accesses are not
-    properly aligned. The option SAFE_IO avoids such problems but will 
-    often be slower on those machines that support misaligned access 
-    (especially so if care is taken to align the input  and output byte 
-    arrays on 32-bit word boundaries). If SAFE_IO is not defined it is 
-    assumed that access to byte arrays as if they are arrays of 32-bit 
-    words will not cause problems when such accesses are misaligned.
-*/
-#if 0
-#define SAFE_IO
-#endif
-
-/*  7. LOOP UNROLLING
-
-    The code for encryption and decrytpion cycles through a number of rounds
-    that can be implemented either in a loop or by expanding the code into a 
-    long sequence of instructions, the latter producing a larger program but
-    one that will often be much faster. The latter is called loop unrolling.
-    There are also potential speed advantages in expanding two iterations in
-    a loop with half the number of iterations, which is called partial loop
-    unrolling.  The following options allow partial or full loop unrolling 
-    to be set independently for encryption and decryption
-*/
-#if 1
-#define ENC_UNROLL  FULL
-#elif 0
-#define ENC_UNROLL  PARTIAL
-#else
-#define ENC_UNROLL  NONE
-#endif
-
-#if 1
-#define DEC_UNROLL  FULL
-#elif 0
-#define DEC_UNROLL  PARTIAL
-#else
-#define DEC_UNROLL  NONE
-#endif
-
-/*  8. FIXED OR DYNAMIC TABLES
-
-    When this section is included the tables used by the code are comipled 
-    statically into the binary file.  Otherwise they are computed once when 
-    the code is first used.
-*/
-#if 1
-#define FIXED_TABLES
-#endif
-
-/*  9. FAST FINITE FIELD OPERATIONS
-
-    If this section is included, tables are used to provide faster finite 
-    field arithmetic (this has no effect if FIXED_TABLES is defined).
-*/
-#if 1
-#define FF_TABLES
-#endif
-
-/*  10. INTERNAL STATE VARIABLE FORMAT
-
-    The internal state of Rijndael is stored in a number of local 32-bit 
-    word varaibles which can be defined either as an array or as individual 
-    names variables. Include this section if you want to store these local
-    varaibles in arrays. Otherwise individual local variables will be used.
-*/
-#if 1
-#define ARRAYS
-#endif
-
-/* In this implementation the columns of the state array are each held in
-   32-bit words. The state array can be held in various ways: in an array
-   of words, in a number of individual word variables or in a number of 
-   processor registers. The following define maps a variable name x and
-   a column number c to the way the state array variable is to be held.
-   The first define below maps the state into an array x[c] whereas the 
-   second form maps the state into a number of individual variables x0,
-   x1, etc.  Another form could map individual state colums to machine
-   register names.
-*/
-
-#if defined(ARRAYS)
-#define s(x,c) x[c]
-#else
-#define s(x,c) x##c
-#endif
-
-/*  11. VARIABLE BLOCK SIZE SPEED
-
-    This section is only relevant if you wish to use the variable block
-    length feature of the code.  Include this section if you place more
-    emphasis on speed rather than code size.
-*/
-#if 1
-#define FAST_VARIABLE
-#endif
-
-/*  12. INTERNAL TABLE CONFIGURATION
-
-    This cipher proceeds by repeating in a number of cycles known as 'rounds'
-    which are implemented by a round function which can optionally be speeded
-    up using tables.  The basic tables are each 256 32-bit words, with either 
-    one or four tables being required for each round function depending on
-    how much speed is required. The encryption and decryption round functions
-    are different and the last encryption and decrytpion round functions are
-    different again making four different round functions in all.
-
-    This means that:
-      1. Normal encryption and decryption rounds can each use either 0, 1 
-         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
-      2. The last encryption and decryption rounds can also use either 0, 1 
-         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
-
-    Include or exclude the appropriate definitions below to set the number
-    of tables used by this implementation.
-*/
-
-#if 1   /* set tables for the normal encryption round */
-#define ENC_ROUND   FOUR_TABLES
-#elif 0
-#define ENC_ROUND   ONE_TABLE
-#else
-#define ENC_ROUND   NO_TABLES
-#endif
-
-#if 1   /* set tables for the last encryption round */
-#define LAST_ENC_ROUND  FOUR_TABLES
-#elif 0
-#define LAST_ENC_ROUND  ONE_TABLE
-#else
-#define LAST_ENC_ROUND  NO_TABLES
-#endif
-
-#if 1   /* set tables for the normal decryption round */
-#define DEC_ROUND   FOUR_TABLES
-#elif 0
-#define DEC_ROUND   ONE_TABLE
-#else
-#define DEC_ROUND   NO_TABLES
-#endif
-
-#if 1   /* set tables for the last decryption round */
-#define LAST_DEC_ROUND  FOUR_TABLES
-#elif 0
-#define LAST_DEC_ROUND  ONE_TABLE
-#else
-#define LAST_DEC_ROUND  NO_TABLES
-#endif
-
-/*  The decryption key schedule can be speeded up with tables in the same
-    way that the round functions can.  Include or exclude the following 
-    defines to set this requirement.
-*/
-#if 1
-#define KEY_SCHED   FOUR_TABLES
-#elif 0
-#define KEY_SCHED   ONE_TABLE
-#else
-#define KEY_SCHED   NO_TABLES
-#endif
-
-/* END OF CONFIGURATION OPTIONS */
-
-#define NO_TABLES   0   /* DO NOT CHANGE */
-#define ONE_TABLE   1   /* DO NOT CHANGE */
-#define FOUR_TABLES 4   /* DO NOT CHANGE */
-#define NONE        0   /* DO NOT CHANGE */
-#define PARTIAL     1   /* DO NOT CHANGE */
-#define FULL        2   /* DO NOT CHANGE */
-
-#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE 
> 32)
-#error An illegal block size has been specified.
-#endif  
-
-#if !defined(BLOCK_SIZE)
-#define RC_LENGTH    29
-#else
-#define RC_LENGTH   5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11)
-#endif
-
-/* Disable at least some poor combinations of options */
-
-#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
-#undef  LAST_ENC_ROUND
-#define LAST_ENC_ROUND  NO_TABLES
-#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
-#undef  LAST_ENC_ROUND
-#define LAST_ENC_ROUND  ONE_TABLE 
-#endif
-
-#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
-#undef  ENC_UNROLL
-#define ENC_UNROLL  NONE
-#endif
-
-#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
-#undef  LAST_DEC_ROUND
-#define LAST_DEC_ROUND  NO_TABLES
-#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
-#undef  LAST_DEC_ROUND
-#define LAST_DEC_ROUND  ONE_TABLE 
-#endif
-
-#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
-#undef  DEC_UNROLL
-#define DEC_UNROLL  NONE
-#endif
-
-/*  upr(x,n):  rotates bytes within words by n positions, moving bytes to
-               higher index positions with wrap around into low positions
-    ups(x,n):  moves bytes by n positions to higher index positions in 
-               words but without wrap around
-    bval(x,n): extracts a byte from a word
-
-    NOTE:      The definitions given here are intended only for use with 
-               unsigned variables and with shift counts that are compile
-               time constants
-*/
-
-#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
-#if defined(_MSC_VER)
-#define upr(x,n)        _lrotl((aes_32t)(x), 8 * (n))
-#else
-#define upr(x,n)        ((aes_32t)(x) << 8 * (n) | (aes_32t)(x) >> 32 - 8 * 
(n))
-#endif
-#define ups(x,n)        ((aes_32t)(x) << 8 * (n))
-#define bval(x,n)       ((aes_08t)((x) >> 8 * (n)))
-#define bytes2word(b0, b1, b2, b3)  \
-        (((aes_32t)(b3) << 24) | ((aes_32t)(b2) << 16) | ((aes_32t)(b1) << 8) 
| (b0))
-#endif
-
-#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
-#define upr(x,n)        ((aes_32t)(x) >> 8 * (n) | (aes_32t)(x) << 32 - 8 * 
(n))
-#define ups(x,n)        ((aes_32t)(x) >> 8 * (n)))
-#define bval(x,n)       ((aes_08t)((x) >> 24 - 8 * (n)))
-#define bytes2word(b0, b1, b2, b3)  \
-        (((aes_32t)(b0) << 24) | ((aes_32t)(b1) << 16) | ((aes_32t)(b2) << 8) 
| (b3))
-#endif
-
-#if defined(SAFE_IO)
-
-#define word_in(x)      bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
-#define word_out(x,v)   { (x)[0] ^= bval(v,0); (x)[1] ^= bval(v,1);   \
-                          (x)[2] ^= bval(v,2); (x)[3] ^= bval(v,3);   }
-
-#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
-
-#define word_in(x)      *(aes_32t*)(x)
-#define word_out(x,v)   *(aes_32t*)(x) ^= (v)
-
-#else
-
-#if !defined(bswap_32)
-#if !defined(_MSC_VER)
-#define _lrotl(x,n)     ((aes_32t)(x) <<  n | (aes_32t)(x) >> 32 - n)
-#endif
-#define bswap_32(x)     ((_lrotl((x),8) & 0x00ff00ff) | (_lrotl((x),24) & 
0xff00ff00)) 
-#endif
-
-#warn using slow bswap
-#define word_in(x)      bswap_32(*(aes_32t*)(x))
-#define word_out(x,v)   *(aes_32t*)(x) ^= bswap_32(v)
-
-#endif
-
-/* the finite field modular polynomial and elements */
-
-#define WPOLY   0x011b
-#define BPOLY     0x1b
-
-/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
-
-#define m1  0x80808080
-#define m2  0x7f7f7f7f
-#define FFmulX(x)  ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
-
-/* The following defines provide alternative definitions of FFmulX that might
-   give improved performance if a fast 32-bit multiply is not available. Note
-   that a temporary variable u needs to be defined where FFmulX is used.
-
-#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | 
(u >> 6)) 
-#define m4  (0x01010101 * BPOLY)
-#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) 
-*/
-
-/* Work out which tables are needed for the different options   */
-
-#ifdef  AES_ASM
-#ifdef  ENC_ROUND
-#undef  ENC_ROUND
-#endif
-#define ENC_ROUND   FOUR_TABLES
-#ifdef  LAST_ENC_ROUND
-#undef  LAST_ENC_ROUND
-#endif
-#define LAST_ENC_ROUND  FOUR_TABLES
-#ifdef  DEC_ROUND
-#undef  DEC_ROUND
-#endif
-#define DEC_ROUND   FOUR_TABLES
-#ifdef  LAST_DEC_ROUND
-#undef  LAST_DEC_ROUND
-#endif
-#define LAST_DEC_ROUND  FOUR_TABLES
-#ifdef  KEY_SCHED
-#undef  KEY_SCHED
-#define KEY_SCHED   FOUR_TABLES
-#endif
-#endif
-
-#if defined(ENCRYPTION) || defined(AES_ASM)
-#if ENC_ROUND == ONE_TABLE
-#define FT1_SET
-#elif ENC_ROUND == FOUR_TABLES
-#define FT4_SET
-#else
-#define SBX_SET
-#endif
-#if LAST_ENC_ROUND == ONE_TABLE
-#define FL1_SET
-#elif LAST_ENC_ROUND == FOUR_TABLES
-#define FL4_SET
-#elif !defined(SBX_SET)
-#define SBX_SET
-#endif
-#endif
-
-#if defined(DECRYPTION) || defined(AES_ASM)
-#if DEC_ROUND == ONE_TABLE
-#define IT1_SET
-#elif DEC_ROUND == FOUR_TABLES
-#define IT4_SET
-#else
-#define ISB_SET
-#endif
-#if LAST_DEC_ROUND == ONE_TABLE
-#define IL1_SET
-#elif LAST_DEC_ROUND == FOUR_TABLES
-#define IL4_SET
-#elif !defined(ISB_SET)
-#define ISB_SET
-#endif
-#endif
-
-#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
-#if KEY_SCHED == ONE_TABLE
-#define LS1_SET
-#define IM1_SET
-#elif KEY_SCHED == FOUR_TABLES
-#define LS4_SET
-#define IM4_SET
-#elif !defined(SBX_SET)
-#define SBX_SET
-#endif
-#endif
-
-#ifdef  FIXED_TABLES
-#define prefx   extern const
-#else
-#define prefx   extern
-extern aes_08t  tab_init;
-void gen_tabs(void);
-#endif
-
-prefx aes_32t  rcon_tab[29];
-
-#ifdef  SBX_SET
-prefx aes_08t s_box[256];
-#endif
-
-#ifdef  ISB_SET
-prefx aes_08t inv_s_box[256];
-#endif
-
-#ifdef  FT1_SET
-prefx aes_32t ft_tab[256];
-#endif
-
-#ifdef  FT4_SET
-prefx aes_32t ft_tab[4][256];
-#endif
-
-#ifdef  FL1_SET
-prefx aes_32t fl_tab[256];
-#endif
-
-#ifdef  FL4_SET
-prefx aes_32t fl_tab[4][256];
-#endif
-
-#ifdef  IT1_SET
-prefx aes_32t it_tab[256];
-#endif
-
-#ifdef  IT4_SET
-prefx aes_32t it_tab[4][256];
-#endif
-
-#ifdef  IL1_SET
-prefx aes_32t il_tab[256];
-#endif
-
-#ifdef  IL4_SET
-prefx aes_32t il_tab[4][256];
-#endif
-
-#ifdef  LS1_SET
-#ifdef  FL1_SET
-#undef  LS1_SET
-#else
-prefx aes_32t ls_tab[256];
-#endif
-#endif
-
-#ifdef  LS4_SET
-#ifdef  FL4_SET
-#undef  LS4_SET
-#else
-prefx aes_32t ls_tab[4][256];
-#endif
-#endif
-
-#ifdef  IM1_SET
-prefx aes_32t im_tab[256];
-#endif
-
-#ifdef  IM4_SET
-prefx aes_32t im_tab[4][256];
-#endif
-
-/* Set the number of columns in nc.  Note that it is important
-   that nc is a constant which is known at compile time if the
-   highest speed version of the code is needed.
-*/
-
-#if defined(BLOCK_SIZE)
-#define nc  (BLOCK_SIZE >> 2)
-#else
-#define nc  (cx->n_blk >> 2)
-#endif
-
-/* generic definitions of Rijndael macros that use tables    */
-
-#define no_table(x,box,vf,rf,c) bytes2word( \
-    box[bval(vf(x,0,c),rf(0,c))], \
-    box[bval(vf(x,1,c),rf(1,c))], \
-    box[bval(vf(x,2,c),rf(2,c))], \
-    box[bval(vf(x,3,c),rf(3,c))])
-
-#define one_table(x,op,tab,vf,rf,c) \
- (     tab[bval(vf(x,0,c),rf(0,c))] \
-  ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
-  ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
-  ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
-
-#define four_tables(x,tab,vf,rf,c) \
- (  tab[0][bval(vf(x,0,c),rf(0,c))] \
-  ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
-  ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
-  ^ tab[3][bval(vf(x,3,c),rf(3,c))])
-
-#define vf1(x,r,c)  (x)
-#define rf1(r,c)    (r)
-#define rf2(r,c)    ((r-c)&3)
-
-/* perform forward and inverse column mix operation on four bytes in long word 
x in */
-/* parallel. NOTE: x must be a simple variable, NOT an expression in these 
macros.  */
-
-#define dec_fmvars
-#if defined(FM4_SET)    /* not currently used */
-#define fwd_mcol(x)     four_tables(x,fm_tab,vf1,rf1,0)
-#elif defined(FM1_SET)  /* not currently used */
-#define fwd_mcol(x)     one_table(x,upr,fm_tab,vf1,rf1,0)
-#else
-#undef  dec_fmvars
-#define dec_fmvars      aes_32t f1, f2;
-#define fwd_mcol(x)     (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ 
upr(f1, 2) ^ upr(f1, 1))
-#endif
-
-#define dec_imvars
-#if defined(IM4_SET)
-#define inv_mcol(x)     four_tables(x,im_tab,vf1,rf1,0)
-#elif defined(IM1_SET)
-#define inv_mcol(x)     one_table(x,upr,im_tab,vf1,rf1,0)
-#else
-#undef  dec_imvars
-#define dec_imvars      aes_32t    f2, f4, f8, f9;
-#define inv_mcol(x) \
-    (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
-    f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
-#endif
-
-#if defined(FL4_SET)
-#define ls_box(x,c)     four_tables(x,fl_tab,vf1,rf2,c)
-#elif   defined(LS4_SET)
-#define ls_box(x,c)     four_tables(x,ls_tab,vf1,rf2,c)
-#elif defined(FL1_SET)
-#define ls_box(x,c)     one_table(x,upr,fl_tab,vf1,rf2,c)
-#elif defined(LS1_SET)
-#define ls_box(x,c)     one_table(x,upr,ls_tab,vf1,rf2,c)
-#else
-#define ls_box(x,c)     no_table(x,s_box,vf1,rf2,c)
-#endif
-
-#endif
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ *    notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ *    built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ * -------------------------------------------------------------------------
+ * Issue Date: 29/07/2002
+ *
+ * This file contains the compilation options for AES (Rijndael) and code
+ * that is common across encryption, key scheduling and table generation.
+ *
+ *  OPERATION
+ *
+ *  These source code files implement the AES algorithm Rijndael designed by
+ *  Joan Daemen and Vincent Rijmen. The version in aes.c is designed for
+ *  block and key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes) while
+ *  that in aespp.c provides for block and keys sizes of 128, 160, 192, 224
+ *  and 256 bits (16, 20, 24, 28 and 32 bytes).  This file is a common header
+ *  file for these two implementations and for aesref.c, which is a reference
+ *  implementation.
+ *
+ *  This version is designed for flexibility and speed using operations on
+ *  32-bit words rather than operations on bytes.  It provides aes_both fixed
+ *  and  dynamic block and key lengths and can also run with either big or
+ *  little endian internal byte order (see aes.h).  It inputs block and key
+ *  lengths in bytes with the legal values being  16, 24 and 32 for aes.c and
+ *  16, 20, 24, 28 and 32 for aespp.c
+ *
+ *  THE CIPHER INTERFACE
+ *
+ *  aes_08t         (an unsigned  8-bit type)
+ *  aes_32t         (an unsigned 32-bit type)
+ *  aes_fret        (a signed 16 bit type for function return values)
+ *  aes_good        (value != 0, a good return)
+ *  aes_bad         (value == 0, an error return)
+ *  struct aes_ctx  (structure for the cipher encryption context)
+ *  struct aes_ctx  (structure for the cipher decryption context)
+ *  aes_rval        the function return type (aes_fret if not DLL)
+ *
+ *  C subroutine calls:
+ *
+ *    aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
+ *    aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, 
aes_ctx cx[1]);
+ *    aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char 
out_blk[], const aes_ctx cx[1]);
+ *
+ *    aes_rval aes_dec_len(unsigned int blen, aes_ctx cx[1]);
+ *    aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, 
aes_ctx cx[1]);
+ *    aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char 
out_blk[], const aes_ctx cx[1]);
+ *
+ *  IMPORTANT NOTE: If you are using this C interface and your compiler does
+ *  not set the memory used for objects to zero before use, you will need to
+ *  ensure that cx.s_flg is set to zero before using these subroutine calls.
+ *
+ *  C++ aes class subroutines:
+ *
+ *    class AESclass    for encryption
+ *    class AESclass    for decryption
+ *
+ *    aes_rval len(unsigned int blen = 16);
+ *    aes_rval key(const unsigned char in_key[], unsigned int klen);
+ *    aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+ *
+ *    aes_rval len(unsigned int blen = 16);
+ *    aes_rval key(const unsigned char in_key[], unsigned int klen);
+ *    aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
+ *
+ *  The block length inputs to set_block and set_key are in numbers of
+ *  BYTES, not bits.  The calls to subroutines must be made in the above
+ *  order but multiple calls can be made without repeating earlier calls
+ *  if their parameters have not changed. If the cipher block length is
+ *  variable but set_blk has not been called before cipher operations a
+ *  value of 16 is assumed (that is, the AES block size). In contrast to
+ *  earlier versions the block and key length parameters are now checked
+ *  for correctness and the encryption and decryption routines check to
+ *  ensure that an appropriate key has been set before they are called.
+ *
+ *  COMPILATION
+ *
+ *  The files used to provide AES (Rijndael) are
+ *
+ *  a. aes.h for the definitions needed for use in C.
+ *  b. aescpp.h for the definitions needed for use in C++.
+ *  c. aesopt.h for setting compilation options (also includes common
+ *     code).
+ *  d. aescrypt.c for encryption and decrytpion, or
+ *  e. aescrypt.asm for encryption and decryption using assembler code.
+ *  f. aeskey.c for key scheduling.
+ *  g. aestab.c for table loading or generation.
+ *
+ *  The assembler code uses the NASM assembler. The above files provice
+ *  block and key lengths of 16, 24 and 32 bytes (128, 192 and 256 bits).
+ *  If aescrypp.c and aeskeypp.c are used instead of aescrypt.c and
+ *  aeskey.c respectively, the block and key lengths can then be 16, 20,
+ *  24, 28 or 32 bytes. However this code has not been optimised to the
+ *  same extent and is hence slower (esepcially for the AES block size
+ *  of 16 bytes).
+ *
+ *  To compile AES (Rijndael) for use in C code use aes.h and exclude
+ *  the AES_DLL define in aes.h
+ *
+ *  To compile AES (Rijndael) for use in in C++ code use aescpp.h and
+ *  exclude the AES_DLL define in aes.h
+ *
+ *  To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
+ *  aes.h, include the AES_DLL define and compile the DLL.  If using
+ *  the test files to test the DLL, exclude aes.c from the test build
+ *  project and compile it with the same defines as used for the DLL
+ *  (ensure that the DLL path is correct)
+ *
+ *  CONFIGURATION OPTIONS (here and in aes.h)
+ *
+ *  a. define BLOCK_SIZE in aes.h to set the cipher block size (16, 24
+ *     or 32 for the standard code, or 16, 20, 24, 28 or 32 for the
+ *     extended code) or leave this undefined for dynamically variable
+ *     block size (this will result in much slower code).
+ *  b. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
+ *  c. You may need to set PLATFORM_BYTE_ORDER to define the byte order.
+ *  d. If you want the code to run in a specific internal byte order, then
+ *     INTERNAL_BYTE_ORDER must be set accordingly.
+ *  e. set other configuration options decribed below.
+ */
+
+#ifndef _AESOPT_H
+#define _AESOPT_H
+
+/*  START OF CONFIGURATION OPTIONS
+ *
+ *  USE OF DEFINES
+ *
+ *  Later in this section there are a number of defines that control the
+ *  operation of the code.  In each section, the purpose of each define is
+ *  explained so that the relevant form can be included or excluded by
+ *  setting either 1's or 0's respectively on the branches of the related
+ * #if clauses.
+ */
+
+/*  1. PLATFORM SPECIFIC INCLUDES */
+
+#if defined(__CRYPTLIB__) && !defined(INC_ALL) && !defined(INC_CHILD)
+#include "crypt/aes.h"
+#else
+  #include "aes.h"
+#endif
+
+#if (defined(__GNUC__) || defined(__GNU_LIBRARY__)) && !defined(__CYGWIN__)
+#  if defined(__APPLE__)
+#    include <machine/endian.h>
+#  else
+#    include <endian.h>
+#  endif
+//#  include <machine/byteswap.h>
+#elif defined(__CRYPTLIB__)
+#  if defined(INC_ALL)
+#    include "crypt.h"
+#  elif defined(INC_CHILD)
+#    include "../crypt.h"
+#  else
+#    include "crypt.h"
+#  endif
+#  if defined(DATA_LITTLEENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  else
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif defined(_MSC_VER)
+#  include <stdlib.h>
+#elif !defined(WIN32)
+#  include <stdlib.h>
+#  if !defined (_ENDIAN_H)
+#    include <sys/param.h>
+#  else
+#    include _ENDIAN_H
+#  endif
+#endif
+
+/*  2. BYTE ORDER IN 32-BIT WORDS
+ *
+ *  To obtain the highest speed on processors with 32-bit words, this code
+ *  needs to determine the order in which bytes are packed into such words.
+ *  The following block of code is an attempt to capture the most obvious
+ *  ways in which various environemnts define byte order. It may well fail,
+ *  in which case the definitions will need to be set by editing at the
+ *  points marked **** EDIT HERE IF NECESSARY **** below.
+ */
+#define AES_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+#define AES_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+#  if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    if defined(BYTE_ORDER)
+#      if   (BYTE_ORDER == LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#      elif (BYTE_ORDER == BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+#  if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    if defined(_BYTE_ORDER)
+#      if   (_BYTE_ORDER == _LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#      elif (_BYTE_ORDER == _BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif defined(__BYTE_ORDER)
+#  if   (__BYTE_ORDER == __LITTLE_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#  elif (__BYTE_ORDER == __BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+#  endif
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif 1     /* **** EDIT HERE IF NECESSARY **** */
+XX_FIXME
+/*#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
+ * #elif (('1234' >> 24) == '1')
+ #  define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
+ ##elif (('4321' >> 24) == '1')
+ #  define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN */
+#endif
+#endif
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#  error Please set undetermined byte order (lines 233 or 235 of aesopt.h).
+#endif
+
+/*  3. ASSEMBLER SUPPORT
+ *
+ *  If the assembler code is used for encryption and decryption this file only
+ *  provides key scheduling so the following defines are used
+ */
+#ifdef  AES_ASM
+#define ENCRYPTION_KEY_SCHEDULE
+#define DECRYPTION_KEY_SCHEDULE
+#else
+
+/*  4. FUNCTIONS REQUIRED
+ *
+ *  This implementation provides five main subroutines which provide for
+ *  setting block length, setting encryption and decryption keys and for
+ *  encryption and decryption. When the assembler code is not being used
+ *  the following definition blocks allow the selection of the routines
+ *  that are to be included in the compilation.
+ */
+#if 1
+#define ENCRYPTION_KEY_SCHEDULE
+#endif
+
+#if 1
+#define DECRYPTION_KEY_SCHEDULE
+#endif
+
+#if 1
+#define ENCRYPTION
+#endif
+
+#if 1
+#define DECRYPTION
+#endif
+
+#endif
+
+/*  5. BYTE ORDER WITHIN 32 BIT WORDS
+ *
+ *  The fundamental data processing units in Rijndael are 8-bit bytes. The
+ *  input, output and key input are all enumerated arrays of bytes in which
+ *  bytes are numbered starting at zero and increasing to one less than the
+ *  number of bytes in the array in question. This enumeration is only used
+ *  for naming bytes and does not imply any adjacency or order relationship
+ *  from one byte to another. When these inputs and outputs are considered
+ *  as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
+ *  byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
+ *  In this implementation bits are numbered from 0 to 7 starting at the
+ *  numerically least significant end of each byte (bit n represents 2^n).
+ *
+ *  However, Rijndael can be implemented more efficiently using 32-bit
+ *  words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
+ *  into word[n]. While in principle these bytes can be assembled into words
+ *  in any positions, this implementation only supports the two formats in
+ *  which bytes in adjacent positions within words also have adjacent byte
+ *  numbers. This order is called big-endian if the lowest numbered bytes
+ *  in words have the highest numeric significance and little-endian if the
+ *  opposite applies.
+ *
+ *  This code can work in either order irrespective of the order used by the
+ *  machine on which it runs. Normally the internal byte order will be set
+ *  to the order of the processor on which the code is to be run but this
+ *  define can be used to reverse this in special situations
+ */
+#if 1
+#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
+#elif defined(AES_LITTLE_ENDIAN)
+#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
+#elif defined(AES_BIG_ENDIAN)
+#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
+#endif
+
+/*  6. FAST INPUT/OUTPUT OPERATIONS.
+ *
+ *  On some machines it is possible to improve speed by transferring the
+ *  bytes in the input and output arrays to and from the internal 32-bit
+ *  variables by addressing these arrays as if they are arrays of 32-bit
+ *  words.  On some machines this will always be possible but there may
+ *  be a large performance penalty if the byte arrays are not aligned on
+ *  the normal word boundaries. On other machines this technique will
+ *  lead to memory access errors when such 32-bit word accesses are not
+ *  properly aligned. The option SAFE_IO avoids such problems but will
+ *  often be slower on those machines that support misaligned access
+ *  (especially so if care is taken to align the input  and output byte
+ *  arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
+ *  assumed that access to byte arrays as if they are arrays of 32-bit
+ *  words will not cause problems when such accesses are misaligned.
+ */
+#if 0
+#define SAFE_IO
+#endif
+
+/*  7. LOOP UNROLLING
+ *
+ *  The code for encryption and decrytpion cycles through a number of rounds
+ *  that can be implemented either in a loop or by expanding the code into a
+ *  long sequence of instructions, the latter producing a larger program but
+ *  one that will often be much faster. The latter is called loop unrolling.
+ *  There are also potential speed advantages in expanding two iterations in
+ *  a loop with half the number of iterations, which is called partial loop
+ *  unrolling.  The following options allow partial or full loop unrolling
+ *  to be set independently for encryption and decryption
+ */
+#if 1
+#define ENC_UNROLL  FULL
+#elif 0
+#define ENC_UNROLL  PARTIAL
+#else
+#define ENC_UNROLL  NONE
+#endif
+
+#if 1
+#define DEC_UNROLL  FULL
+#elif 0
+#define DEC_UNROLL  PARTIAL
+#else
+#define DEC_UNROLL  NONE
+#endif
+
+/*  8. FIXED OR DYNAMIC TABLES
+ *
+ *  When this section is included the tables used by the code are comipled
+ *  statically into the binary file.  Otherwise they are computed once when
+ *  the code is first used.
+ */
+#if 1
+#define FIXED_TABLES
+#endif
+
+/*  9. FAST FINITE FIELD OPERATIONS
+ *
+ *  If this section is included, tables are used to provide faster finite
+ *  field arithmetic (this has no effect if FIXED_TABLES is defined).
+ */
+#if 1
+#define FF_TABLES
+#endif
+
+/*  10. INTERNAL STATE VARIABLE FORMAT
+ *
+ *  The internal state of Rijndael is stored in a number of local 32-bit
+ *  word varaibles which can be defined either as an array or as individual
+ *  names variables. Include this section if you want to store these local
+ *  varaibles in arrays. Otherwise individual local variables will be used.
+ */
+#if 1
+#define ARRAYS
+#endif
+
+/* In this implementation the columns of the state array are each held in
+ * 32-bit words. The state array can be held in various ways: in an array
+ * of words, in a number of individual word variables or in a number of
+ * processor registers. The following define maps a variable name x and
+ * a column number c to the way the state array variable is to be held.
+ * The first define below maps the state into an array x[c] whereas the
+ * second form maps the state into a number of individual variables x0,
+ * x1, etc.  Another form could map individual state colums to machine
+ * register names.
+ */
+
+#if defined(ARRAYS)
+#define s(x, c) x[c]
+#else
+#define s(x, c) x ## c
+#endif
+
+/*  11. VARIABLE BLOCK SIZE SPEED
+ *
+ *  This section is only relevant if you wish to use the variable block
+ *  length feature of the code.  Include this section if you place more
+ *  emphasis on speed rather than code size.
+ */
+#if 1
+#define FAST_VARIABLE
+#endif
+
+/*  12. INTERNAL TABLE CONFIGURATION
+ *
+ *  This cipher proceeds by repeating in a number of cycles known as 'rounds'
+ *  which are implemented by a round function which can optionally be speeded
+ *  up using tables.  The basic tables are each 256 32-bit words, with either
+ *  one or four tables being required for each round function depending on
+ *  how much speed is required. The encryption and decryption round functions
+ *  are different and the last encryption and decrytpion round functions are
+ *  different again making four different round functions in all.
+ *
+ *  This means that:
+ *    1. Normal encryption and decryption rounds can each use either 0, 1
+ *       or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+ *    2. The last encryption and decryption rounds can also use either 0, 1
+ *       or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
+ *
+ *  Include or exclude the appropriate definitions below to set the number
+ *  of tables used by this implementation.
+ */
+
+#if 1   /* set tables for the normal encryption round */
+#define ENC_ROUND   FOUR_TABLES
+#elif 0
+#define ENC_ROUND   ONE_TABLE
+#else
+#define ENC_ROUND   NO_TABLES
+#endif
+
+#if 1   /* set tables for the last encryption round */
+#define LAST_ENC_ROUND  FOUR_TABLES
+#elif 0
+#define LAST_ENC_ROUND  ONE_TABLE
+#else
+#define LAST_ENC_ROUND  NO_TABLES
+#endif
+
+#if 1   /* set tables for the normal decryption round */
+#define DEC_ROUND   FOUR_TABLES
+#elif 0
+#define DEC_ROUND   ONE_TABLE
+#else
+#define DEC_ROUND   NO_TABLES
+#endif
+
+#if 1   /* set tables for the last decryption round */
+#define LAST_DEC_ROUND  FOUR_TABLES
+#elif 0
+#define LAST_DEC_ROUND  ONE_TABLE
+#else
+#define LAST_DEC_ROUND  NO_TABLES
+#endif
+
+/*  The decryption key schedule can be speeded up with tables in the same
+ *  way that the round functions can.  Include or exclude the following
+ *  defines to set this requirement.
+ */
+#if 1
+#define KEY_SCHED   FOUR_TABLES
+#elif 0
+#define KEY_SCHED   ONE_TABLE
+#else
+#define KEY_SCHED   NO_TABLES
+#endif
+
+/* END OF CONFIGURATION OPTIONS */
+
+#define NO_TABLES   0   /* DO NOT CHANGE */
+#define ONE_TABLE   1   /* DO NOT CHANGE */
+#define FOUR_TABLES 4   /* DO NOT CHANGE */
+#define NONE        0   /* DO NOT CHANGE */
+#define PARTIAL     1   /* DO NOT CHANGE */
+#define FULL        2   /* DO NOT CHANGE */
+
+#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE 
> 32)
+#error An illegal block size has been specified.
+#endif
+
+#if !defined(BLOCK_SIZE)
+#define RC_LENGTH    29
+#else
+#define RC_LENGTH   5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11)
+#endif
+
+/* Disable at least some poor combinations of options */
+
+#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
+#undef  LAST_ENC_ROUND
+#define LAST_ENC_ROUND  NO_TABLES
+#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
+#undef  LAST_ENC_ROUND
+#define LAST_ENC_ROUND  ONE_TABLE
+#endif
+
+#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
+#undef  ENC_UNROLL
+#define ENC_UNROLL  NONE
+#endif
+
+#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
+#undef  LAST_DEC_ROUND
+#define LAST_DEC_ROUND  NO_TABLES
+#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
+#undef  LAST_DEC_ROUND
+#define LAST_DEC_ROUND  ONE_TABLE
+#endif
+
+#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
+#undef  DEC_UNROLL
+#define DEC_UNROLL  NONE
+#endif
+
+/*  upr(x,n):  rotates bytes within words by n positions, moving bytes to
+ *             higher index positions with wrap around into low positions
+ *  ups(x,n):  moves bytes by n positions to higher index positions in
+ *             words but without wrap around
+ *  bval(x,n): extracts a byte from a word
+ *
+ *  NOTE:      The definitions given here are intended only for use with
+ *             unsigned variables and with shift counts that are compile
+ *             time constants
+ */
+
+#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
+#if defined(_MSC_VER)
+#define upr(x, n)        _lrotl((aes_32t) (x), 8 * (n))
+#else
+#define upr(x, n)        ((aes_32t) (x) << 8 * (n) | (aes_32t) (x) >> 32 - 8 * 
(n))
+#endif
+#define ups(x, n)        ((aes_32t) (x) << 8 * (n))
+#define bval(x, n)       ((aes_08t) ((x) >> 8 * (n)))
+#define bytes2word(b0, b1, b2, b3)  \
+    (((aes_32t) (b3) << 24) | ((aes_32t) (b2) << 16) | ((aes_32t) (b1) << 8) | 
(b0))
+#endif
+
+#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
+#define upr(x, n)        ((aes_32t) (x) >> 8 * (n) | (aes_32t) (x) << 32 - 8 * 
(n))
+#define ups(x, n)        ((aes_32t) (x) >> 8 * (n)))
+#define bval(x, n)       ((aes_08t) ((x) >> 24 - 8 * (n)))
+#define bytes2word(b0, b1, b2, b3)  \
+    (((aes_32t) (b0) << 24) | ((aes_32t) (b1) << 16) | ((aes_32t) (b2) << 8) | 
(b3))
+#endif
+
+#if defined(SAFE_IO)
+
+#define word_in(x)      bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
+#define word_out(x, v)   { (x)[0] ^= bval(v, 0); (x)[1] ^= bval(v, 1);   \
+                           (x)[2] ^= bval(v, 2); (x)[3] ^= bval(v, 3);   }
+
+#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
+
+#define word_in(x)      *(aes_32t *) (x)
+#define word_out(x, v)   *(aes_32t *) (x) ^= (v)
+
+#else
+
+#if !defined(bswap_32)
+#if !defined(_MSC_VER)
+#define _lrotl(x, n)     ((aes_32t) (x) <<  n | (aes_32t) (x) >> 32 - n)
+#endif
+#define bswap_32(x)     ((_lrotl((x), 8) & 0x00ff00ff) | (_lrotl((x), 24) & 
0xff00ff00))
+#endif
+
+#warn using slow bswap
+#define word_in(x)      bswap_32(*(aes_32t *) (x))
+#define word_out(x, v)   *(aes_32t *) (x) ^= bswap_32(v)
+
+#endif
+
+/* the finite field modular polynomial and elements */
+
+#define WPOLY   0x011b
+#define BPOLY     0x1b
+
+/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
+
+#define m1  0x80808080
+#define m2  0x7f7f7f7f
+#define FFmulX(x)  ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
+
+/* The following defines provide alternative definitions of FFmulX that might
+ * give improved performance if a fast 32-bit multiply is not available. Note
+ * that a temporary variable u needs to be defined where FFmulX is used.
+ *
+ * #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 
3) | (u >> 6))
+ * #define m4  (0x01010101 * BPOLY)
+ * #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
+ */
+
+/* Work out which tables are needed for the different options   */
+
+#ifdef  AES_ASM
+#ifdef  ENC_ROUND
+#undef  ENC_ROUND
+#endif
+#define ENC_ROUND   FOUR_TABLES
+#ifdef  LAST_ENC_ROUND
+#undef  LAST_ENC_ROUND
+#endif
+#define LAST_ENC_ROUND  FOUR_TABLES
+#ifdef  DEC_ROUND
+#undef  DEC_ROUND
+#endif
+#define DEC_ROUND   FOUR_TABLES
+#ifdef  LAST_DEC_ROUND
+#undef  LAST_DEC_ROUND
+#endif
+#define LAST_DEC_ROUND  FOUR_TABLES
+#ifdef  KEY_SCHED
+#undef  KEY_SCHED
+#define KEY_SCHED   FOUR_TABLES
+#endif
+#endif
+
+#if defined(ENCRYPTION) || defined(AES_ASM)
+#if ENC_ROUND == ONE_TABLE
+#define FT1_SET
+#elif ENC_ROUND == FOUR_TABLES
+#define FT4_SET
+#else
+#define SBX_SET
+#endif
+#if LAST_ENC_ROUND == ONE_TABLE
+#define FL1_SET
+#elif LAST_ENC_ROUND == FOUR_TABLES
+#define FL4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#if defined(DECRYPTION) || defined(AES_ASM)
+#if DEC_ROUND == ONE_TABLE
+#define IT1_SET
+#elif DEC_ROUND == FOUR_TABLES
+#define IT4_SET
+#else
+#define ISB_SET
+#endif
+#if LAST_DEC_ROUND == ONE_TABLE
+#define IL1_SET
+#elif LAST_DEC_ROUND == FOUR_TABLES
+#define IL4_SET
+#elif !defined(ISB_SET)
+#define ISB_SET
+#endif
+#endif
+
+#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
+#if KEY_SCHED == ONE_TABLE
+#define LS1_SET
+#define IM1_SET
+#elif KEY_SCHED == FOUR_TABLES
+#define LS4_SET
+#define IM4_SET
+#elif !defined(SBX_SET)
+#define SBX_SET
+#endif
+#endif
+
+#ifdef  FIXED_TABLES
+#define prefx   extern const
+#else
+#define prefx   extern
+extern aes_08t tab_init;
+void gen_tabs(void);
+#endif
+
+prefx aes_32t rcon_tab[29];
+
+#ifdef  SBX_SET
+prefx aes_08t s_box[256];
+#endif
+
+#ifdef  ISB_SET
+prefx aes_08t inv_s_box[256];
+#endif
+
+#ifdef  FT1_SET
+prefx aes_32t ft_tab[256];
+#endif
+
+#ifdef  FT4_SET
+prefx aes_32t ft_tab[4][256];
+#endif
+
+#ifdef  FL1_SET
+prefx aes_32t fl_tab[256];
+#endif
+
+#ifdef  FL4_SET
+prefx aes_32t fl_tab[4][256];
+#endif
+
+#ifdef  IT1_SET
+prefx aes_32t it_tab[256];
+#endif
+
+#ifdef  IT4_SET
+prefx aes_32t it_tab[4][256];
+#endif
+
+#ifdef  IL1_SET
+prefx aes_32t il_tab[256];
+#endif
+
+#ifdef  IL4_SET
+prefx aes_32t il_tab[4][256];
+#endif
+
+#ifdef  LS1_SET
+#ifdef  FL1_SET
+#undef  LS1_SET
+#else
+prefx aes_32t ls_tab[256];
+#endif
+#endif
+
+#ifdef  LS4_SET
+#ifdef  FL4_SET
+#undef  LS4_SET
+#else
+prefx aes_32t ls_tab[4][256];
+#endif
+#endif
+
+#ifdef  IM1_SET
+prefx aes_32t im_tab[256];
+#endif
+
+#ifdef  IM4_SET
+prefx aes_32t im_tab[4][256];
+#endif
+
+/* Set the number of columns in nc.  Note that it is important
+ * that nc is a constant which is known at compile time if the
+ * highest speed version of the code is needed.
+ */
+
+#if defined(BLOCK_SIZE)
+#define nc  (BLOCK_SIZE >> 2)
+#else
+#define nc  (cx->n_blk >> 2)
+#endif
+
+/* generic definitions of Rijndael macros that use tables    */
+
+#define no_table(x, box, vf, rf, c) bytes2word( \
+        box[bval(vf(x, 0, c), rf(0, c))], \
+        box[bval(vf(x, 1, c), rf(1, c))], \
+        box[bval(vf(x, 2, c), rf(2, c))], \
+        box[bval(vf(x, 3, c), rf(3, c))])
+
+#define one_table(x, op, tab, vf, rf, c) \
+    (tab[bval(vf(x, 0, c), rf(0, c))] \
+     ^ op(tab[bval(vf(x, 1, c), rf(1, c))], 1) \
+     ^ op(tab[bval(vf(x, 2, c), rf(2, c))], 2) \
+     ^ op(tab[bval(vf(x, 3, c), rf(3, c))], 3))
+
+#define four_tables(x, tab, vf, rf, c) \
+    (tab[0][bval(vf(x, 0, c), rf(0, c))] \
+     ^ tab[1][bval(vf(x, 1, c), rf(1, c))] \
+     ^ tab[2][bval(vf(x, 2, c), rf(2, c))] \
+     ^ tab[3][bval(vf(x, 3, c), rf(3, c))])
+
+#define vf1(x, r, c)  (x)
+#define rf1(r, c)    (r)
+#define rf2(r, c)    ((r - c) & 3)
+
+/* perform forward and inverse column mix operation on four bytes in long word 
x in */
+/* parallel. NOTE: x must be a simple variable, NOT an expression in these 
macros.  */
+
+#define dec_fmvars
+#if defined(FM4_SET)    /* not currently used */
+#define fwd_mcol(x)     four_tables(x, fm_tab, vf1, rf1, 0)
+#elif defined(FM1_SET)  /* not currently used */
+#define fwd_mcol(x)     one_table(x, upr, fm_tab, vf1, rf1, 0)
+#else
+#undef  dec_fmvars
+#define dec_fmvars      aes_32t f1, f2;
+#define fwd_mcol(x)     (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ 
upr(f1, 2) ^ upr(f1, 1))
+#endif
+
+#define dec_imvars
+#if defined(IM4_SET)
+#define inv_mcol(x)     four_tables(x, im_tab, vf1, rf1, 0)
+#elif defined(IM1_SET)
+#define inv_mcol(x)     one_table(x, upr, im_tab, vf1, rf1, 0)
+#else
+#undef  dec_imvars
+#define dec_imvars      aes_32t f2, f4, f8, f9;
+#define inv_mcol(x) \
+    (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
+     f2 ^= f4 ^ f8 ^ upr(f2 ^ f9, 3) ^ upr(f4 ^ f9, 2) ^ upr(f9, 1))
+#endif
+
+#if defined(FL4_SET)
+#define ls_box(x, c)     four_tables(x, fl_tab, vf1, rf2, c)
+#elif   defined(LS4_SET)
+#define ls_box(x, c)     four_tables(x, ls_tab, vf1, rf2, c)
+#elif defined(FL1_SET)
+#define ls_box(x, c)     one_table(x, upr, fl_tab, vf1, rf2, c)
+#elif defined(LS1_SET)
+#define ls_box(x, c)     one_table(x, upr, ls_tab, vf1, rf2, c)
+#else
+#define ls_box(x, c)     no_table(x, s_box, vf1, rf2, c)
+#endif
+
+#endif

=== modified file 'i3/aeshash/aestab.c'
--- i3/aeshash/aestab.c 2009-12-11 22:49:11 +0000
+++ i3/aeshash/aestab.c 2010-02-11 11:49:47 +0000
@@ -1,494 +1,504 @@
-/*
- -------------------------------------------------------------------------
- Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
- All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary 
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright 
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products 
-      built using this software without specific written permission. 
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness 
- and fitness for purpose.
- -------------------------------------------------------------------------
- Issue Date: 29/07/2002
-*/
-
-#include "aesopt.h"
-
-#if defined(FIXED_TABLES) || !defined(FF_TABLES) 
-
-/*  finite field arithmetic operations */
-
-#define f2(x)   ((x<<1) ^ (((x>>7) & 1) * WPOLY))
-#define f4(x)   ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
-#define f8(x)   ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
-                        ^ (((x>>5) & 4) * WPOLY))
-#define f3(x)   (f2(x) ^ x)
-#define f9(x)   (f8(x) ^ x)
-#define fb(x)   (f8(x) ^ f2(x) ^ x)
-#define fd(x)   (f8(x) ^ f4(x) ^ x)
-#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))
-
-#endif
-
-#if defined(FIXED_TABLES)
-
-#define sb_data(w) \
-    w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
-    w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
-    w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
-    w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
-    w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
-    w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
-    w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
-    w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
-    w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
-    w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
-    w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
-    w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
-    w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
-    w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
-    w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
-    w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
-    w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
-    w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
-    w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
-    w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
-    w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
-    w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
-    w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
-    w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
-    w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
-    w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
-    w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
-    w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
-    w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
-    w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
-    w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
-    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
-
-#define isb_data(w) \
-    w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
-    w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
-    w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
-    w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
-    w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
-    w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
-    w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
-    w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
-    w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
-    w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
-    w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
-    w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
-    w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
-    w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
-    w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
-    w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
-    w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
-    w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
-    w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
-    w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
-    w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
-    w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
-    w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
-    w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
-    w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
-    w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
-    w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
-    w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
-    w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
-    w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
-    w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
-    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
-
-#define mm_data(w) \
-    w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
-    w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
-    w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
-    w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
-    w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
-    w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
-    w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
-    w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
-    w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
-    w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
-    w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
-    w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
-    w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
-    w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
-    w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
-    w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
-    w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
-    w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
-    w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
-    w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
-    w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
-    w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
-    w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
-    w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
-    w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
-    w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
-    w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
-    w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
-    w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
-    w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
-    w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
-    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
-
-#define h0(x)   (x)
-
-/*  These defines are used to ensure tables are generated in the 
-    right format depending on the internal byte order required
-*/
-
-#define w0(p)   bytes2word(p, 0, 0, 0)
-#define w1(p)   bytes2word(0, p, 0, 0)
-#define w2(p)   bytes2word(0, 0, p, 0)
-#define w3(p)   bytes2word(0, 0, 0, p)
-
-/*  Number of elements required in this table for different
-    block and key lengths is:
-
-    Rcon Table      key length (bytes)
-    Length          16  20  24  28  32
-                ---------------------
-    block     16 |  10   9   8   7   7
-    length    20 |  14  11  10   9   9
-    (bytes)   24 |  19  15  12  11  11
-              28 |  24  19  16  13  13
-              32 |  29  23  19  17  14
-
-    this table can be a table of bytes if the key schedule
-    code is adjusted accordingly
-*/
-
-#define u0(p)   bytes2word(f2(p), p, p, f3(p))
-#define u1(p)   bytes2word(f3(p), f2(p), p, p)
-#define u2(p)   bytes2word(p, f3(p), f2(p), p)
-#define u3(p)   bytes2word(p, p, f3(p), f2(p))
-
-#define v0(p)   bytes2word(fe(p), f9(p), fd(p), fb(p))
-#define v1(p)   bytes2word(fb(p), fe(p), f9(p), fd(p))
-#define v2(p)   bytes2word(fd(p), fb(p), fe(p), f9(p))
-#define v3(p)   bytes2word(f9(p), fd(p), fb(p), fe(p))
-
-const aes_32t rcon_tab[29] =
-{
-    w0(0x01), w0(0x02), w0(0x04), w0(0x08),
-    w0(0x10), w0(0x20), w0(0x40), w0(0x80),
-    w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8),
-    w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f),
-    w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6),
-    w0(0x97), w0(0x35), w0(0x6a), w0(0xd4),
-    w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef),
-    w0(0xc5)
-};
-
-#ifdef  SBX_SET
-const aes_08t s_box[256] = { sb_data(h0) };
-#endif
-#ifdef  ISB_SET
-const aes_08t inv_s_box[256] = { isb_data(h0) };
-#endif
-
-#ifdef  FT1_SET
-const aes_32t ft_tab[256] = { sb_data(u0) };
-#endif
-#ifdef  FT4_SET
-const aes_32t ft_tab[4][256] = 
-    { {  sb_data(u0) }, {  sb_data(u1) }, {  sb_data(u2) }, {  sb_data(u3) } };
-#endif
-
-#ifdef  FL1_SET
-const aes_32t fl_tab[256] = { sb_data(w0) };
-#endif
-#ifdef  FL4_SET
-const aes_32t fl_tab[4][256] = 
-    { {  sb_data(w0) }, {  sb_data(w1) }, {  sb_data(w2) }, {  sb_data(w3) } };
-#endif
-
-#ifdef  IT1_SET
-const aes_32t it_tab[256] = { isb_data(v0) };
-#endif
-#ifdef  IT4_SET
-const aes_32t it_tab[4][256] =
-    { { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } };
-#endif
-
-#ifdef  IL1_SET
-const aes_32t il_tab[256] = { isb_data(w0) };
-#endif
-#ifdef  IL4_SET
-const aes_32t il_tab[4][256] = 
-    { { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } };
-#endif
-
-#ifdef  LS1_SET
-const aes_32t ls_tab[256] = { sb_data(w0) };
-#endif
-#ifdef  LS4_SET
-const aes_32t ls_tab[4][256] =
-    { {  sb_data(w0) }, {  sb_data(w1) }, {  sb_data(w2) }, {  sb_data(w3) } };
-#endif
-
-#ifdef  IM1_SET
-const aes_32t im_tab[256] = { mm_data(v0) };
-#endif
-#ifdef  IM4_SET
-const aes_32t im_tab[4][256] = 
-    { {  mm_data(v0) }, {  mm_data(v1) }, {  mm_data(v2) }, {  mm_data(v3) } };
-#endif
-
-#else   /* dynamic table generation */
-
-aes_08t tab_init = 0;
-
-#define const
-
-aes_32t  rcon_tab[RC_LENGTH];
-
-#ifdef  SBX_SET
-aes_08t s_box[256];
-#endif
-#ifdef  ISB_SET
-aes_08t inv_s_box[256];
-#endif
-
-#ifdef  FT1_SET
-aes_32t ft_tab[256];
-#endif
-#ifdef  FT4_SET
-aes_32t ft_tab[4][256];
-#endif
-
-#ifdef  FL1_SET
-aes_32t fl_tab[256];
-#endif
-#ifdef  FL4_SET
-aes_32t fl_tab[4][256];
-#endif
-
-#ifdef  IT1_SET
-aes_32t it_tab[256];
-#endif
-#ifdef  IT4_SET
-aes_32t it_tab[4][256];
-#endif
-
-#ifdef  IL1_SET
-aes_32t il_tab[256];
-#endif
-#ifdef  IL4_SET
-aes_32t il_tab[4][256];
-#endif
-
-#ifdef  LS1_SET
-aes_32t ls_tab[256];
-#endif
-#ifdef  LS4_SET
-aes_32t ls_tab[4][256];
-#endif
-
-#ifdef  IM1_SET
-aes_32t im_tab[256];
-#endif
-#ifdef  IM4_SET
-aes_32t im_tab[4][256];
-#endif
-
-#if !defined(FF_TABLES)
-
-/*  Generate the tables for the dynamic table option
-
-    It will generally be sensible to use tables to compute finite 
-    field multiplies and inverses but where memory is scarse this 
-    code might sometimes be better. But it only has effect during
-    initialisation so its pretty unimportant in overall terms.
-*/
-
-/*  return 2 ^ (n - 1) where n is the bit number of the highest bit
-    set in x with x in the range 1 < x < 0x00000200.   This form is
-    used so that locals within fi can be bytes rather than words
-*/
-
-static aes_08t hibit(const aes_32t x)
-{   aes_08t r = (aes_08t)((x >> 1) | (x >> 2));
-    
-    r |= (r >> 2);
-    r |= (r >> 4);
-    return (r + 1) >> 1;
-}
-
-/* return the inverse of the finite field element x */
-
-static aes_08t fi(const aes_08t x)
-{   aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-
-    if(x < 2) return x;
-
-    for(;;)
-    {
-        if(!n1) return v1;
-
-        while(n2 >= n1)
-        {   
-            n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
-        }
-        
-        if(!n2) return v2;
-
-        while(n1 >= n2)
-        {   
-            n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
-        }
-    }
-}
-
-#else
-
-/* define the finite field multiplies required for Rijndael */
-
-#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
-#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
-#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
-#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
-#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
-#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
-#define fi(x) ((x) ?   pow[255 - log[x]]: 0)
-
-#endif
-
-/* The forward and inverse affine transformations used in the S-box */
-
-#define fwd_affine(x) \
-    (w = (aes_32t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 
0x63^(aes_08t)(w^(w>>8)))
-
-#define inv_affine(x) \
-    (w = (aes_32t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(aes_08t)(w^(w>>8)))
-
-void gen_tabs(void)
-{   aes_32t  i, w;
-
-#if defined(FF_TABLES)
-
-    aes_08t  pow[512], log[256];
-
-    /*  log and power tables for GF(2^8) finite field with
-        WPOLY as modular polynomial - the simplest primitive
-        root is 0x03, used here to generate the tables
-    */
-
-    i = 0; w = 1; 
-    do
-    {   
-        pow[i] = (aes_08t)w;
-        pow[i + 255] = (aes_08t)w;
-        log[w] = (aes_08t)i++;
-        w ^=  (w << 1) ^ (w & 0x80 ? WPOLY : 0);
-    }
-    while (w != 1);
-
-#endif
-
-    for(i = 0, w = 1; i < RC_LENGTH; ++i)
-    {
-        rcon_tab[i] = bytes2word(w, 0, 0, 0);
-        w = f2(w);
-    }
-
-    for(i = 0; i < 256; ++i)
-    {   aes_08t    b;
-
-        b = fwd_affine(fi((aes_08t)i));
-        w = bytes2word(f2(b), b, b, f3(b));
-
-#ifdef  SBX_SET
-        s_box[i] = b;
-#endif
-
-#ifdef  FT1_SET                 /* tables for a normal encryption round */
-        ft_tab[i] = w;
-#endif
-#ifdef  FT4_SET
-        ft_tab[0][i] = w;
-        ft_tab[1][i] = upr(w,1);
-        ft_tab[2][i] = upr(w,2);
-        ft_tab[3][i] = upr(w,3);
-#endif
-        w = bytes2word(b, 0, 0, 0);
-
-#ifdef  FL1_SET                 /* tables for last encryption round (may also  
 */
-        fl_tab[i] = w;          /* be used in the key schedule)                
 */
-#endif
-#ifdef  FL4_SET
-        fl_tab[0][i] = w;
-        fl_tab[1][i] = upr(w,1);
-        fl_tab[2][i] = upr(w,2);
-        fl_tab[3][i] = upr(w,3);
-#endif
-
-#ifdef  LS1_SET                 /* table for key schedule if fl_tab above is   
 */
-        ls_tab[i] = w;          /* not of the required form                    
 */
-#endif
-#ifdef  LS4_SET
-        ls_tab[0][i] = w;
-        ls_tab[1][i] = upr(w,1);
-        ls_tab[2][i] = upr(w,2);
-        ls_tab[3][i] = upr(w,3);
-#endif
-
-        b = fi(inv_affine((aes_08t)i));
-        w = bytes2word(fe(b), f9(b), fd(b), fb(b));
-
-#ifdef  IM1_SET                 /* tables for the inverse mix column operation 
 */
-        im_tab[b] = w;
-#endif
-#ifdef  IM4_SET
-        im_tab[0][b] = w;
-        im_tab[1][b] = upr(w,1);
-        im_tab[2][b] = upr(w,2);
-        im_tab[3][b] = upr(w,3);
-#endif
-
-#ifdef  ISB_SET
-        inv_s_box[i] = b;
-#endif
-#ifdef  IT1_SET                 /* tables for a normal decryption round */
-        it_tab[i] = w;
-#endif
-#ifdef  IT4_SET
-        it_tab[0][i] = w;
-        it_tab[1][i] = upr(w,1);
-        it_tab[2][i] = upr(w,2);
-        it_tab[3][i] = upr(w,3);
-#endif
-        w = bytes2word(b, 0, 0, 0);
-#ifdef  IL1_SET                 /* tables for last decryption round */
-        il_tab[i] = w;
-#endif
-#ifdef  IL4_SET
-        il_tab[0][i] = w;
-        il_tab[1][i] = upr(w,1);
-        il_tab[2][i] = upr(w,2);
-        il_tab[3][i] = upr(w,3);
-#endif
-    }
-
-    tab_init = 1;
-}
-
-#endif
+/*
+ * -------------------------------------------------------------------------
+ * Copyright (c) 2001, Dr Brian Gladman <brg@xxxxxxxxxxxxx>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ * 1. distributions of this source code include the above copyright
+ *    notice, this list of conditions and the following disclaimer;
+ *
+ * 2. distributions in binary form include the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in the documentation and/or other associated materials;
+ *
+ * 3. the copyright holder's name is not used to endorse products
+ *    built using this software without specific written permission.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and fitness for purpose.
+ * -------------------------------------------------------------------------
+ * Issue Date: 29/07/2002
+ */
+
+#include "aesopt.h"
+
+#if defined(FIXED_TABLES) || !defined(FF_TABLES)
+
+/*  finite field arithmetic operations */
+
+#define f2(x)   ((x << 1) ^ (((x >> 7) & 1) * WPOLY))
+#define f4(x)   ((x << 2) ^ (((x >> 6) & 1) * WPOLY) ^ (((x >> 6) & 2) * 
WPOLY))
+#define f8(x)   ((x << 3) ^ (((x >> 5) & 1) * WPOLY) ^ (((x >> 5) & 2) * 
WPOLY) \
+                 ^ (((x >> 5) & 4) * WPOLY))
+#define f3(x)   (f2(x) ^ x)
+#define f9(x)   (f8(x) ^ x)
+#define fb(x)   (f8(x) ^ f2(x) ^ x)
+#define fd(x)   (f8(x) ^ f4(x) ^ x)
+#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))
+
+#endif
+
+#if defined(FIXED_TABLES)
+
+#define sb_data(w) \
+    w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5), \
+    w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76), \
+    w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0), \
+    w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0), \
+    w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc), \
+    w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15), \
+    w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a), \
+    w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75), \
+    w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0), \
+    w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84), \
+    w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b), \
+    w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf), \
+    w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85), \
+    w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8), \
+    w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5), \
+    w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2), \
+    w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17), \
+    w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73), \
+    w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88), \
+    w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb), \
+    w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c), \
+    w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79), \
+    w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9), \
+    w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08), \
+    w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6), \
+    w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a), \
+    w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e), \
+    w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e), \
+    w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94), \
+    w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf), \
+    w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68), \
+    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
+
+#define isb_data(w) \
+    w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38), \
+    w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb), \
+    w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87), \
+    w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb), \
+    w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d), \
+    w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e), \
+    w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2), \
+    w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25), \
+    w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16), \
+    w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92), \
+    w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda), \
+    w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84), \
+    w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a), \
+    w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06), \
+    w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02), \
+    w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b), \
+    w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea), \
+    w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73), \
+    w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85), \
+    w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e), \
+    w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89), \
+    w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b), \
+    w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20), \
+    w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4), \
+    w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31), \
+    w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f), \
+    w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d), \
+    w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef), \
+    w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0), \
+    w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61), \
+    w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26), \
+    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
+
+#define mm_data(w) \
+    w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07), \
+    w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f), \
+    w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17), \
+    w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f), \
+    w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27), \
+    w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f), \
+    w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37), \
+    w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f), \
+    w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47), \
+    w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f), \
+    w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57), \
+    w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f), \
+    w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67), \
+    w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f), \
+    w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77), \
+    w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f), \
+    w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87), \
+    w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f), \
+    w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97), \
+    w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f), \
+    w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7), \
+    w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf), \
+    w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7), \
+    w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf), \
+    w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7), \
+    w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf), \
+    w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7), \
+    w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf), \
+    w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7), \
+    w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef), \
+    w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7), \
+    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
+
+#define h0(x)   (x)
+
+/*  These defines are used to ensure tables are generated in the
+ *  right format depending on the internal byte order required
+ */
+
+#define w0(p)   bytes2word(p, 0, 0, 0)
+#define w1(p)   bytes2word(0, p, 0, 0)
+#define w2(p)   bytes2word(0, 0, p, 0)
+#define w3(p)   bytes2word(0, 0, 0, p)
+
+/*  Number of elements required in this table for different
+ *  block and key lengths is:
+ *
+ *  Rcon Table      key length (bytes)
+ *  Length          16  20  24  28  32
+ *              ---------------------
+ *  block     16 |  10   9   8   7   7
+ *  length    20 |  14  11  10   9   9
+ *  (bytes)   24 |  19  15  12  11  11
+ *            28 |  24  19  16  13  13
+ *            32 |  29  23  19  17  14
+ *
+ *  this table can be a table of bytes if the key schedule
+ *  code is adjusted accordingly
+ */
+
+#define u0(p)   bytes2word(f2(p), p, p, f3(p))
+#define u1(p)   bytes2word(f3(p), f2(p), p, p)
+#define u2(p)   bytes2word(p, f3(p), f2(p), p)
+#define u3(p)   bytes2word(p, p, f3(p), f2(p))
+
+#define v0(p)   bytes2word(fe(p), f9(p), fd(p), fb(p))
+#define v1(p)   bytes2word(fb(p), fe(p), f9(p), fd(p))
+#define v2(p)   bytes2word(fd(p), fb(p), fe(p), f9(p))
+#define v3(p)   bytes2word(f9(p), fd(p), fb(p), fe(p))
+
+const aes_32t rcon_tab[29] =
+{
+    w0(0x01), w0(0x02), w0(0x04), w0(0x08),
+    w0(0x10), w0(0x20), w0(0x40), w0(0x80),
+    w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8),
+    w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f),
+    w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6),
+    w0(0x97), w0(0x35), w0(0x6a), w0(0xd4),
+    w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef),
+    w0(0xc5)
+};
+
+#ifdef  SBX_SET
+const aes_08t s_box[256] = { sb_data(h0) };
+#endif
+#ifdef  ISB_SET
+const aes_08t inv_s_box[256] = { isb_data(h0) };
+#endif
+
+#ifdef  FT1_SET
+const aes_32t ft_tab[256] = { sb_data(u0) };
+#endif
+#ifdef  FT4_SET
+const aes_32t ft_tab[4][256] =
+{ {  sb_data(u0) }, {  sb_data(u1) }, {  sb_data(u2) }, {  sb_data(u3) } };
+#endif
+
+#ifdef  FL1_SET
+const aes_32t fl_tab[256] = { sb_data(w0) };
+#endif
+#ifdef  FL4_SET
+const aes_32t fl_tab[4][256] =
+{ {  sb_data(w0) }, {  sb_data(w1) }, {  sb_data(w2) }, {  sb_data(w3) } };
+#endif
+
+#ifdef  IT1_SET
+const aes_32t it_tab[256] = { isb_data(v0) };
+#endif
+#ifdef  IT4_SET
+const aes_32t it_tab[4][256] =
+{ { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } };
+#endif
+
+#ifdef  IL1_SET
+const aes_32t il_tab[256] = { isb_data(w0) };
+#endif
+#ifdef  IL4_SET
+const aes_32t il_tab[4][256] =
+{ { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } };
+#endif
+
+#ifdef  LS1_SET
+const aes_32t ls_tab[256] = { sb_data(w0) };
+#endif
+#ifdef  LS4_SET
+const aes_32t ls_tab[4][256] =
+{ {  sb_data(w0) }, {  sb_data(w1) }, {  sb_data(w2) }, {  sb_data(w3) } };
+#endif
+
+#ifdef  IM1_SET
+const aes_32t im_tab[256] = { mm_data(v0) };
+#endif
+#ifdef  IM4_SET
+const aes_32t im_tab[4][256] =
+{ {  mm_data(v0) }, {  mm_data(v1) }, {  mm_data(v2) }, {  mm_data(v3) } };
+#endif
+
+#else   /* dynamic table generation */
+
+aes_08t tab_init = 0;
+
+#define const
+
+aes_32t rcon_tab[RC_LENGTH];
+
+#ifdef  SBX_SET
+aes_08t s_box[256];
+#endif
+#ifdef  ISB_SET
+aes_08t inv_s_box[256];
+#endif
+
+#ifdef  FT1_SET
+aes_32t ft_tab[256];
+#endif
+#ifdef  FT4_SET
+aes_32t ft_tab[4][256];
+#endif
+
+#ifdef  FL1_SET
+aes_32t fl_tab[256];
+#endif
+#ifdef  FL4_SET
+aes_32t fl_tab[4][256];
+#endif
+
+#ifdef  IT1_SET
+aes_32t it_tab[256];
+#endif
+#ifdef  IT4_SET
+aes_32t it_tab[4][256];
+#endif
+
+#ifdef  IL1_SET
+aes_32t il_tab[256];
+#endif
+#ifdef  IL4_SET
+aes_32t il_tab[4][256];
+#endif
+
+#ifdef  LS1_SET
+aes_32t ls_tab[256];
+#endif
+#ifdef  LS4_SET
+aes_32t ls_tab[4][256];
+#endif
+
+#ifdef  IM1_SET
+aes_32t im_tab[256];
+#endif
+#ifdef  IM4_SET
+aes_32t im_tab[4][256];
+#endif
+
+#if !defined(FF_TABLES)
+
+/*  Generate the tables for the dynamic table option
+ *
+ *  It will generally be sensible to use tables to compute finite
+ *  field multiplies and inverses but where memory is scarse this
+ *  code might sometimes be better. But it only has effect during
+ *  initialisation so its pretty unimportant in overall terms.
+ */
+
+/*  return 2 ^ (n - 1) where n is the bit number of the highest bit
+ *  set in x with x in the range 1 < x < 0x00000200.   This form is
+ *  used so that locals within fi can be bytes rather than words
+ */
+
+static aes_08t hibit(const aes_32t x)
+{
+    aes_08t r = (aes_08t) ((x >> 1) | (x >> 2));
+
+    r |= (r >> 2);
+    r |= (r >> 4);
+    return (r + 1) >> 1;
+}
+
+/* return the inverse of the finite field element x */
+
+static aes_08t fi(const aes_08t x)
+{
+    aes_08t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
+
+    if (x < 2) {
+        return x;
+    }
+
+    for (;; ) {
+        if (!n1) {
+            return v1;
+        }
+
+        while (n2 >= n1) {
+            n2 /= n1;
+            p2 ^= p1 * n2;
+            v2 ^= v1 * n2;
+            n2  = hibit(p2);
+        }
+
+        if (!n2) {
+            return v2;
+        }
+
+        while (n1 >= n2) {
+            n1 /= n2;
+            p1 ^= p2 * n1;
+            v1 ^= v2 * n1;
+            n1  = hibit(p1);
+        }
+    }
+}
+
+#else
+
+/* define the finite field multiplies required for Rijndael */
+
+#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
+#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
+#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
+#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
+#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
+#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
+#define fi(x) ((x) ?   pow[255 - log[x]] : 0)
+
+#endif
+
+/* The forward and inverse affine transformations used in the S-box */
+
+#define fwd_affine(x) \
+    (w = (aes_32t) x, w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4), 0x63 ^ 
(aes_08t) (w ^ (w >> 8)))
+
+#define inv_affine(x) \
+    (w = (aes_32t) x, w = (w << 1) ^ (w << 3) ^ (w << 6), 0x05 ^ (aes_08t) (w 
^ (w >> 8)))
+
+void gen_tabs(void)
+{
+    aes_32t i, w;
+
+#if defined(FF_TABLES)
+
+    aes_08t pow[512], log[256];
+
+    /*  log and power tables for GF(2^8) finite field with
+     *  WPOLY as modular polynomial - the simplest primitive
+     *  root is 0x03, used here to generate the tables
+     */
+
+    i = 0;
+    w = 1;
+    do {
+        pow[i]       = (aes_08t) w;
+        pow[i + 255] = (aes_08t) w;
+        log[w]       = (aes_08t) i++;
+        w           ^=  (w << 1) ^ (w & 0x80 ? WPOLY : 0);
+    } while (w != 1);
+
+#endif
+
+    for (i = 0, w = 1; i < RC_LENGTH; ++i) {
+        rcon_tab[i] = bytes2word(w, 0, 0, 0);
+        w           = f2(w);
+    }
+
+    for (i = 0; i < 256; ++i) {
+        aes_08t b;
+
+        b            = fwd_affine(fi((aes_08t) i));
+        w            = bytes2word(f2(b), b, b, f3(b));
+
+#ifdef  SBX_SET
+        s_box[i]     = b;
+#endif
+
+#ifdef  FT1_SET                 /* tables for a normal encryption round */
+        ft_tab[i]    = w;
+#endif
+#ifdef  FT4_SET
+        ft_tab[0][i] = w;
+        ft_tab[1][i] = upr(w, 1);
+        ft_tab[2][i] = upr(w, 2);
+        ft_tab[3][i] = upr(w, 3);
+#endif
+        w            = bytes2word(b, 0, 0, 0);
+
+#ifdef  FL1_SET                 /* tables for last encryption round (may also  
 */
+        fl_tab[i]    = w;       /* be used in the key schedule)                
 */
+#endif
+#ifdef  FL4_SET
+        fl_tab[0][i] = w;
+        fl_tab[1][i] = upr(w, 1);
+        fl_tab[2][i] = upr(w, 2);
+        fl_tab[3][i] = upr(w, 3);
+#endif
+
+#ifdef  LS1_SET                 /* table for key schedule if fl_tab above is   
 */
+        ls_tab[i]    = w;       /* not of the required form                    
 */
+#endif
+#ifdef  LS4_SET
+        ls_tab[0][i] = w;
+        ls_tab[1][i] = upr(w, 1);
+        ls_tab[2][i] = upr(w, 2);
+        ls_tab[3][i] = upr(w, 3);
+#endif
+
+        b            = fi(inv_affine((aes_08t) i));
+        w            = bytes2word(fe(b), f9(b), fd(b), fb(b));
+
+#ifdef  IM1_SET                 /* tables for the inverse mix column operation 
 */
+        im_tab[b]    = w;
+#endif
+#ifdef  IM4_SET
+        im_tab[0][b] = w;
+        im_tab[1][b] = upr(w, 1);
+        im_tab[2][b] = upr(w, 2);
+        im_tab[3][b] = upr(w, 3);
+#endif
+
+#ifdef  ISB_SET
+        inv_s_box[i] = b;
+#endif
+#ifdef  IT1_SET                 /* tables for a normal decryption round */
+        it_tab[i]    = w;
+#endif
+#ifdef  IT4_SET
+        it_tab[0][i] = w;
+        it_tab[1][i] = upr(w, 1);
+        it_tab[2][i] = upr(w, 2);
+        it_tab[3][i] = upr(w, 3);
+#endif
+        w            = bytes2word(b, 0, 0, 0);
+#ifdef  IL1_SET                 /* tables for last decryption round */
+        il_tab[i]    = w;
+#endif
+#ifdef  IL4_SET
+        il_tab[0][i] = w;
+        il_tab[1][i] = upr(w, 1);
+        il_tab[2][i] = upr(w, 2);
+        il_tab[3][i] = upr(w, 3);
+#endif
+    }
+
+    tab_init = 1;
+}
+
+#endif

=== modified file 'i3/chord/api.c'
--- i3/chord/api.c      2009-12-11 22:49:11 +0000
+++ i3/chord/api.c      2010-02-11 11:49:47 +0000
@@ -1,171 +1,173 @@
-/* Common API functions */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include "chord.h"
-
-#define RUNTIME_DIR "/var/run/chord"
-#ifndef PATH_MAX
-#define PATH_MAX 256
-#endif
-static char shmid_filename[PATH_MAX];
-
-#ifndef SIM_CHORD
-static int sp[2];  /* Socket pair for communication between the two layers */
-static chordID *shared_data;
-static int shmid;
-#else
-static chordID LeftId, RightId;
-#endif
-
-#ifndef SIM_CHORD 
-
-/* route: forward message M towards the root of key K. */
-void chord_route(chordID *k, char *data, int len)
-{
-  byte buf[BUFSIZE];
-
-  if (send(sp[0], buf, pack_data(buf, CHORD_ROUTE, 
-                                DEF_TTL, k, len, (unsigned char*)data), 0) < 0)
-    weprintf("send failed:");  /* ignore errors */
-}
-
-/**********************************************************************/
-
-/* init: initialize chord server, return socket descriptor */
-int chord_init(char *conf_file)
-{
-  FILE *fp;
-  struct stat stat_buf;
-    
-  if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) < 0)
-    eprintf("socket_pair failed:");
-
-  if ((shmid = shmget(IPC_PRIVATE, 1024, 0644 | IPC_CREAT)) == -1)
-    eprintf("shmget failed:");
-
-#ifndef CCURED  
-  shared_data = (chordID *) shmat(shmid, (void *) 0, 0);
-  if ((char *) shared_data == (char *) -1)
-    eprintf("shmate failed:");
-#else
-  {
-    void * shared_data_ret = shmat(shmid, (void *) 0, 0);
-    if ((ulong) shared_data_ret == (ulong) -1)
-      eprintf("shmate failed:");
-    shared_data = (chordID *)__trusted_cast(__mkptr_size(shared_data_ret,
-                                                         1024));
-  }
-#endif
-
-  /* Write out PID, shmid for monitor */
-  memset( &stat_buf, 0, sizeof(struct stat) );
-  if( stat( RUNTIME_DIR, &stat_buf ) || !S_ISDIR(stat_buf.st_mode) ) {
-    weprintf( "Could not open %s; not writing shmid\n", RUNTIME_DIR );
-
-  } else {
-    sprintf( shmid_filename, "%s/chord.%u.shmid", RUNTIME_DIR,
-            getpid() ); 
-    fp = fopen( shmid_filename, "w");
-    if (fp == NULL) {
-      weprintf("Could not write %s\n", shmid_filename);
-    } else {
-      if( (fprintf( fp, "%d\n", shmid ) <= 0) ||
-         fflush( fp ) || fclose( fp ) ) {
-       eprintf("Could not write %s\n", shmid_filename );
-      }
-    }
-  }
-  
-  /* Catch all crashes/kills and cleanup */
-  signal(SIGHUP, chord_cleanup);
-  signal(SIGINT, chord_cleanup);
-  signal(SIGILL, chord_cleanup);
-  signal(SIGABRT, chord_cleanup);
-  signal(SIGALRM, chord_cleanup);
-  signal(SIGFPE, chord_cleanup);
-  signal(SIGSEGV, chord_cleanup);
-  signal(SIGPIPE, chord_cleanup);
-  signal(SIGTERM, chord_cleanup);
-  signal(SIGCHLD, chord_cleanup); /* If Chord process dies, exit */
-  signal(SIGBUS, chord_cleanup);
-
-  if (!fork()) {  /* child */
-    chord_main(conf_file, sp[1]);
-  }
-
-  return sp[0];
-}
-
-/**********************************************************************/
-
-void chord_cleanup(int signum)
-{
-  shmdt(shared_data);
-  shmctl(shmid, IPC_RMID, NULL);
-  unlink(shmid_filename);
-  signal(SIGABRT, SIG_DFL);
-  abort();
-}
-
-/**********************************************************************/
-
-/* deliver: upcall */
-void chord_deliver(int n, uchar *data)
-{
-  /* Convert to I3 format... by stripping off the Chord header */
-  send(sp[1], data, n, 0);
-}
-
-#endif
-
-/**********************************************************************/
-
-/* get_range: returns the range (l,r] that this node is responsible for */
-void chord_get_range(chordID *l, chordID *r)
-{
-#ifndef SIM_CHORD
-  *l = shared_data[0];
-  *r = shared_data[1];
-#else
-  *l = LeftId;
-  *r = RightId;
-#endif
-}
-
-
-
-/**********************************************************************/
-
-void chord_update_range(chordID *l, chordID *r)
-{
-  //printf("update_range(");
-  //print_chordID(l);
-  //printf(" - ");
-  //print_chordID(r);
-  //printf(")\n");
-#ifndef SIM_CHORD
-  shared_data[0] = *l;
-  shared_data[1] = *r;
-#else
-  LeftId = *l;
-  RightId = *r;
-#endif
-}
-
-/**********************************************************************/
-
-int chord_is_local(chordID *x)
-{
-  chordID l, r;
-
-  chord_get_range(&l, &r);
-  return equals(x, &r) || is_between(x, &l, &r);
-}
+/* Common API functions */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include "chord.h"
+
+#define RUNTIME_DIR "/var/run/chord"
+#ifndef PATH_MAX
+#define PATH_MAX 256
+#endif
+static char shmid_filename[PATH_MAX];
+
+#ifndef SIM_CHORD
+static int sp[2];  /* Socket pair for communication between the two layers */
+static chordID *shared_data;
+static int shmid;
+#else
+static chordID LeftId, RightId;
+#endif
+
+#ifndef SIM_CHORD
+
+/* route: forward message M towards the root of key K. */
+void chord_route(chordID *k, char *data, int len)
+{
+    byte buf[BUFSIZE];
+
+    if (send(sp[0], buf, pack_data(buf, CHORD_ROUTE,
+                                   DEF_TTL, k, len, (unsigned char *) data), 
0) < 0) {
+        weprintf("send failed:"); /* ignore errors */
+    }
+}
+
+/**********************************************************************/
+
+/* init: initialize chord server, return socket descriptor */
+int chord_init(char *conf_file)
+{
+    FILE *fp;
+    struct stat stat_buf;
+
+    if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) < 0) {
+        eprintf("socket_pair failed:");
+    }
+
+    if ((shmid = shmget(IPC_PRIVATE, 1024, 0644 | IPC_CREAT)) == -1) {
+        eprintf("shmget failed:");
+    }
+
+#ifndef CCURED
+    shared_data = (chordID *) shmat(shmid, (void *) 0, 0);
+    if ((char *) shared_data == (char *) -1) {
+        eprintf("shmate failed:");
+    }
+#else
+    {
+        void *shared_data_ret = shmat(shmid, (void *) 0, 0);
+        if ((ulong) shared_data_ret == (ulong) - 1) {
+            eprintf("shmate failed:");
+        }
+        shared_data = (chordID *) __trusted_cast(__mkptr_size(shared_data_ret,
+                                                              1024));
+    }
+#endif
+
+    /* Write out PID, shmid for monitor */
+    memset( &stat_buf, 0, sizeof(struct stat));
+    if (stat( RUNTIME_DIR, &stat_buf ) || !S_ISDIR(stat_buf.st_mode)) {
+        weprintf( "Could not open %s; not writing shmid\n", RUNTIME_DIR );
+    } else {
+        sprintf( shmid_filename, "%s/chord.%u.shmid", RUNTIME_DIR,
+                 getpid());
+        fp = fopen( shmid_filename, "w");
+        if (fp == NULL) {
+            weprintf("Could not write %s\n", shmid_filename);
+        } else {
+            if ((fprintf( fp, "%d\n", shmid ) <= 0) ||
+                fflush( fp ) || fclose( fp )) {
+                eprintf("Could not write %s\n", shmid_filename );
+            }
+        }
+    }
+
+    /* Catch all crashes/kills and cleanup */
+    signal(SIGHUP, chord_cleanup);
+    signal(SIGINT, chord_cleanup);
+    signal(SIGILL, chord_cleanup);
+    signal(SIGABRT, chord_cleanup);
+    signal(SIGALRM, chord_cleanup);
+    signal(SIGFPE, chord_cleanup);
+    signal(SIGSEGV, chord_cleanup);
+    signal(SIGPIPE, chord_cleanup);
+    signal(SIGTERM, chord_cleanup);
+    signal(SIGCHLD, chord_cleanup); /* If Chord process dies, exit */
+    signal(SIGBUS, chord_cleanup);
+
+    if (!fork()) { /* child */
+        chord_main(conf_file, sp[1]);
+    }
+
+    return sp[0];
+}
+
+/**********************************************************************/
+
+void chord_cleanup(int signum)
+{
+    shmdt(shared_data);
+    shmctl(shmid, IPC_RMID, NULL);
+    unlink(shmid_filename);
+    signal(SIGABRT, SIG_DFL);
+    abort();
+}
+
+/**********************************************************************/
+
+/* deliver: upcall */
+void chord_deliver(int n, uchar *data)
+{
+    /* Convert to I3 format... by stripping off the Chord header */
+    send(sp[1], data, n, 0);
+}
+
+#endif
+
+/**********************************************************************/
+
+/* get_range: returns the range (l,r] that this node is responsible for */
+void chord_get_range(chordID *l, chordID *r)
+{
+#ifndef SIM_CHORD
+    *l = shared_data[0];
+    *r = shared_data[1];
+#else
+    *l = LeftId;
+    *r = RightId;
+#endif
+}
+
+/**********************************************************************/
+
+void chord_update_range(chordID *l, chordID *r)
+{
+    //printf("update_range(");
+    //print_chordID(l);
+    //printf(" - ");
+    //print_chordID(r);
+    //printf(")\n");
+#ifndef SIM_CHORD
+    shared_data[0] = *l;
+    shared_data[1] = *r;
+#else
+    LeftId         = *l;
+    RightId        = *r;
+#endif
+}
+
+/**********************************************************************/
+
+int chord_is_local(chordID *x)
+{
+    chordID l, r;
+
+    chord_get_range(&l, &r);
+    return equals(x, &r) || is_between(x, &l, &r);
+}

=== modified file 'i3/chord/chord.c'
--- i3/chord/chord.c    2010-01-12 12:35:31 +0000
+++ i3/chord/chord.c    2010-02-11 11:49:47 +0000
@@ -1,203 +1,204 @@
-/* Chord server loop */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <assert.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/utsname.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/time.h>
-#include "chord.h"
-#include "../utils/gen_utils.h"
-
-/* globals */
-extern Server *srv_ref;        /* For use in stabilize() */
-Server srv;
-Node well_known[MAX_WELLKNOWN];
-int nknown;
-Key KeyArray[MAX_KEY_NUM];
-int NumKeys;
-
-
-/**********************************************************************/
-
-void
-chord_main(char *conf_file, int parent_sock)
-{
-    fd_set interesting, readable;
-    int nfound, nfds;
-    struct in_addr ia;
-    char id[4*ID_LEN];
-    FILE *fp;
-    int64_t stabilize_wait;
-    struct timeval timeout;
-    
-    setprogname("chord");
-    srandom(getpid() ^ time(0));
-    memset(&srv, 0, sizeof(Server));
-    srv.to_fix_finger = NFINGERS-1;
-
-    fp = fopen(conf_file, "r");
-    if (fp == NULL)
-       eprintf("fopen(%s,\"r\") failed:", conf_file);
-    if (fscanf(fp, "%hd", (short*)&srv.node.port) != 1)
-        eprintf("Didn't find port in \"%s\"", conf_file);
-    if (fscanf(fp, " %s\n", id) != 1)
-        eprintf("Didn't find id in \"%s\"", conf_file);
-    srv.node.id = atoid(id);
-
-    /* Figure out one's own address somehow */
-    srv.node.addr = ntohl(get_addr());
-
-    ia.s_addr = htonl(srv.node.addr);
-    fprintf(stderr, "Chord started.\n");
-    fprintf(stderr, "id="); print_id(stderr, &srv.node.id); 
-    fprintf(stderr, "\n");
-    fprintf(stderr, "ip=%s\n", inet_ntoa(ia));
-    fprintf(stderr, "port=%d\n", srv.node.port);
-
-    initialize(&srv);
-    srv_ref = &srv;
-    join(&srv, fp);
-    fclose(fp);
-
-    FD_ZERO(&interesting);
-    FD_SET(srv.in_sock, &interesting);
-    FD_SET(parent_sock, &interesting);
-    nfds = MAX(srv.in_sock, parent_sock) + 1;
-
-    NumKeys = read_keys(ACCLIST_FILE, KeyArray, MAX_KEY_NUM);
-    if (NumKeys == -1) {
-      printf("Error opening file: %s\n", ACCLIST_FILE);
-    }
-    if (NumKeys == 0) {
-      printf("No key found in %s\n", ACCLIST_FILE);
-    }
-
-    /* Loop on input */
-    for (;;) {
-       readable = interesting;
-       stabilize_wait = (int64_t)(srv.next_stabilize_us - wall_time());
-       stabilize_wait = MAX(stabilize_wait,0);
-       timeout.tv_sec = stabilize_wait / 1000000UL;
-       timeout.tv_usec = stabilize_wait % 1000000UL;
-       nfound = select(nfds, &readable, NULL, NULL, &timeout);
-       if (nfound < 0 && errno == EINTR) {
-            continue;
-       }
-       if (nfound == 0) {
-           stabilize_wait = (int64_t)(srv.next_stabilize_us - wall_time());
-           if( stabilize_wait <= 0 ) {
-               stabilize( &srv );
-           }
-           continue;
-       }
-       if (FD_ISSET(srv.in_sock, &readable)) {
-           handle_packet(srv.in_sock);
-       }
-       else if (FD_ISSET(parent_sock, &readable)) {
-           handle_packet(parent_sock);
-       }
-       else {
-           assert(0);
-       }
-    }
-}
-
-/**********************************************************************/
-
-/* initialize: set up sockets and such <yawn> */
-void 
-initialize(Server *srv)
-{
-    int flags;
-    struct sockaddr_in sin, sout;
-
-    setservent(1);
-
-    memset(&sin, 0, sizeof(sin));
-    sin.sin_family = AF_INET;
-    sin.sin_port = htons(srv->node.port);
-    sin.sin_addr.s_addr = htonl(INADDR_ANY);
-
-    srv->in_sock = socket(AF_INET, SOCK_DGRAM, 0);
-    if (srv->in_sock < 0)
-       eprintf("socket failed:");
-    
-    if (bind(srv->in_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0)
-       eprintf("bind failed:");
-       
-    /* non-blocking i/o */
-    flags = fcntl(srv->in_sock, F_GETFL);
-    flags |= O_NONBLOCK;
-    fcntl(srv->in_sock, F_SETFL, flags);
-
-    /* outgoing socket */
-    memset(&sout, 0, sizeof(sout));
-    sout.sin_family = AF_INET;
-    sout.sin_port = htons(0);
-    sout.sin_addr.s_addr = htonl(INADDR_ANY);
-
-    srv->out_sock = socket(AF_INET, SOCK_DGRAM, 0);
-    if (srv->out_sock < 0)
-       eprintf("socket failed:");
-
-    if (bind(srv->out_sock, (struct sockaddr *) &sout, sizeof(sout)) < 0)
-       eprintf("bind failed:");
-}
-
-/**********************************************************************/
-
-/* handle_packet: snarf packet from network and dispatch */
-void
-handle_packet(int network)
-{
-    int packet_len, from_len;
-    struct sockaddr_in from;
-    byte buf[BUFSIZE];
-
-    from_len = sizeof(from);
-    packet_len = recvfrom(network, buf, sizeof(buf), 0,
-                         (struct sockaddr *) &from, (unsigned int*)&from_len);
-    if (packet_len < 0) {
-       if (errno != EAGAIN) {
-          weprintf("recvfrom failed:");  /* ignore errors for now */
-          return;
-       }
-       weprintf("handle_packet: EAGAIN");
-       return;   /* pick up this packet later */
-    }
-    dispatch(&srv, packet_len, buf);
-}
-
-
-/**********************************************************************/
-
-int
-read_keys(char *file, Key *keyarray, int max_num_keys)
-{
-  int   i;
-  FILE *fp;
-
-  fp = fopen(file, "r");
-  if (fp == NULL) 
-    return -1;
-
-  for (i = 0; i < max_num_keys; i++) {
-    if (fscanf(fp, "%20c\n", (char *)&keyarray[i]) != 1) 
-      break;
-  }
-  return i;
-  
-  fclose(fp);
-}
-
-
+/* Chord server loop */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/utsname.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/time.h>
+#include "chord.h"
+#include "../utils/gen_utils.h"
+
+/* globals */
+extern Server *srv_ref; /* For use in stabilize() */
+Server srv;
+Node well_known[MAX_WELLKNOWN];
+int nknown;
+Key KeyArray[MAX_KEY_NUM];
+int NumKeys;
+
+
+/**********************************************************************/
+
+void chord_main(char *conf_file, int parent_sock)
+{
+    fd_set interesting, readable;
+    int nfound, nfds;
+    struct in_addr ia;
+    char id[4 * ID_LEN];
+    FILE *fp;
+    int64_t stabilize_wait;
+    struct timeval timeout;
+
+    setprogname("chord");
+    srandom(getpid() ^ time(0));
+    memset(&srv, 0, sizeof(Server));
+    srv.to_fix_finger = NFINGERS - 1;
+
+    fp                = fopen(conf_file, "r");
+    if (fp == NULL) {
+        eprintf("fopen(%s,\"r\") failed:", conf_file);
+    }
+    if (fscanf(fp, "%hd", (short *) &srv.node.port) != 1) {
+        eprintf("Didn't find port in \"%s\"", conf_file);
+    }
+    if (fscanf(fp, " %s\n", id) != 1) {
+        eprintf("Didn't find id in \"%s\"", conf_file);
+    }
+    srv.node.id   = atoid(id);
+
+    /* Figure out one's own address somehow */
+    srv.node.addr = ntohl(get_addr());
+
+    ia.s_addr     = htonl(srv.node.addr);
+    fprintf(stderr, "Chord started.\n");
+    fprintf(stderr, "id=");
+    print_id(stderr, &srv.node.id);
+    fprintf(stderr, "\n");
+    fprintf(stderr, "ip=%s\n", inet_ntoa(ia));
+    fprintf(stderr, "port=%d\n", srv.node.port);
+
+    initialize(&srv);
+    srv_ref = &srv;
+    join(&srv, fp);
+    fclose(fp);
+
+    FD_ZERO(&interesting);
+    FD_SET(srv.in_sock, &interesting);
+    FD_SET(parent_sock, &interesting);
+    nfds    = MAX(srv.in_sock, parent_sock) + 1;
+
+    NumKeys = read_keys(ACCLIST_FILE, KeyArray, MAX_KEY_NUM);
+    if (NumKeys == -1) {
+        printf("Error opening file: %s\n", ACCLIST_FILE);
+    }
+    if (NumKeys == 0) {
+        printf("No key found in %s\n", ACCLIST_FILE);
+    }
+
+    /* Loop on input */
+    for (;; ) {
+        readable        = interesting;
+        stabilize_wait  = (int64_t) (srv.next_stabilize_us - wall_time());
+        stabilize_wait  = MAX(stabilize_wait, 0);
+        timeout.tv_sec  = stabilize_wait / 1000000UL;
+        timeout.tv_usec = stabilize_wait % 1000000UL;
+        nfound          = select(nfds, &readable, NULL, NULL, &timeout);
+        if (nfound < 0 && errno == EINTR) {
+            continue;
+        }
+        if (nfound == 0) {
+            stabilize_wait = (int64_t) (srv.next_stabilize_us - wall_time());
+            if (stabilize_wait <= 0) {
+                stabilize( &srv );
+            }
+            continue;
+        }
+        if (FD_ISSET(srv.in_sock, &readable)) {
+            handle_packet(srv.in_sock);
+        } else if (FD_ISSET(parent_sock, &readable))   {
+            handle_packet(parent_sock);
+        } else {
+            assert(0);
+        }
+    }
+}
+
+/**********************************************************************/
+
+/* initialize: set up sockets and such <yawn> */
+void initialize(Server *srv)
+{
+    int flags;
+    struct sockaddr_in sin, sout;
+
+    setservent(1);
+
+    memset(&sin, 0, sizeof(sin));
+    sin.sin_family      = AF_INET;
+    sin.sin_port        = htons(srv->node.port);
+    sin.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    srv->in_sock        = socket(AF_INET, SOCK_DGRAM, 0);
+    if (srv->in_sock < 0) {
+        eprintf("socket failed:");
+    }
+
+    if (bind(srv->in_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+        eprintf("bind failed:");
+    }
+
+    /* non-blocking i/o */
+    flags  = fcntl(srv->in_sock, F_GETFL);
+    flags |= O_NONBLOCK;
+    fcntl(srv->in_sock, F_SETFL, flags);
+
+    /* outgoing socket */
+    memset(&sout, 0, sizeof(sout));
+    sout.sin_family      = AF_INET;
+    sout.sin_port        = htons(0);
+    sout.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    srv->out_sock        = socket(AF_INET, SOCK_DGRAM, 0);
+    if (srv->out_sock < 0) {
+        eprintf("socket failed:");
+    }
+
+    if (bind(srv->out_sock, (struct sockaddr *) &sout, sizeof(sout)) < 0) {
+        eprintf("bind failed:");
+    }
+}
+
+/**********************************************************************/
+
+/* handle_packet: snarf packet from network and dispatch */
+void handle_packet(int network)
+{
+    int packet_len, from_len;
+    struct sockaddr_in from;
+    byte buf[BUFSIZE];
+
+    from_len   = sizeof(from);
+    packet_len = recvfrom(network, buf, sizeof(buf), 0,
+                          (struct sockaddr *) &from, (unsigned int *) 
&from_len);
+    if (packet_len < 0) {
+        if (errno != EAGAIN) {
+            weprintf("recvfrom failed:"); /* ignore errors for now */
+            return;
+        }
+        weprintf("handle_packet: EAGAIN");
+        return;  /* pick up this packet later */
+    }
+    dispatch(&srv, packet_len, buf);
+}
+
+/**********************************************************************/
+
+int read_keys(char *file, Key *keyarray, int max_num_keys)
+{
+    int i;
+    FILE *fp;
+
+    fp = fopen(file, "r");
+    if (fp == NULL) {
+        return -1;
+    }
+
+    for (i = 0; i < max_num_keys; i++) {
+        if (fscanf(fp, "%20c\n", (char *) &keyarray[i]) != 1) {
+            break;
+        }
+    }
+    return i;
+
+    fclose(fp);
+}

=== modified file 'i3/chord/chord.h'
--- i3/chord/chord.h    2010-01-12 12:35:31 +0000
+++ i3/chord/chord.h    2010-02-11 11:49:47 +0000
@@ -1,351 +1,348 @@
-#include <sys/types.h>
-#include <netinet/in.h>
-#ifdef __APPLE__
-#include <inttypes.h>  // Need uint64_t
-#endif
-#include <stdio.h>
-#include "debug.h"
-
-#ifndef INCL_CHORD_H
-#define INCL_CHORD_H
-
-typedef struct Finger Finger;
-typedef struct Node Node;
-typedef struct Server Server;
-
-
-#define NELEMS(a) (sizeof(a) / sizeof(a[0]))
-#ifndef FALSE
-#define FALSE 0
-#define TRUE  1
-#endif
-
-/* whether a finger is passive or active */
-#define F_PASSIVE 0
-#define F_ACTIVE  1
-
-//#define SIM_CHORD
-
-#ifdef SIM_CHORD 
-enum {
-    NBITS        = 16,             /* # bits of an ID */         
-    ID_LEN       = NBITS/8,        /* bytes per ID */
-    NFINGERS     = NBITS,          /* # fingers per node */
-    NSUCCESSORS  = 3,              /* # successors kept */
-    NPREDECESSORS = 3,             /* # predecessors kep */
-    BUFSIZE      = 65535,          /* buffer for packets */
-    STABILIZE_PERIOD = 1*1000000,  /* in usec  */
-    MAX_WELLKNOWN = 4,             /* maximum number of "seed" servers */
-    MAX_SIMJOIN = 4,               /* maximum number of servers 
-                                   * contacted simultaneously when joining
-                                   */
-    PING_THRESH = 3,               /* this many unanswered pings are allowed */
-    DEF_TTL      = 64,             /* default TTL for multi-hop packets */
-};
-#else
-enum {
-    NBITS        = 160,            /* # bits per ID, same as SHA-1 output */
-    ID_LEN       = NBITS/8,        /* bytes per ID */
-    NFINGERS     = NBITS,          /* # fingers per node */
-    NSUCCESSORS  = 8,              /* # successors kept */
-    NPREDECESSORS = 3,             /* # predecessors kept */
-    STABILIZE_PERIOD = 1*1000000,  /* in usec */
-    BUFSIZE      = 65535,          /* buffer for packets */
-    MAX_WELLKNOWN = 50,            /* maximum number of other known servers 
-                                   *  (read from configuration file)
-                                   */
-    MAX_SIMJOIN = 4,               /* maximum number of servers 
-                                   * contacted simultaneously when joining
-                                   */
-    PING_THRESH = 5,               /* this many unanswered pings are allowed */
-    DEF_TTL      = 64,             /* default TTL for multi-hop packets */
-};
-#endif /* SIM_CHORD */
-
-/* packet types */
-enum {
-    CHORD_ROUTE = 0,   /* data packet */
-    CHORD_ROUTE_LAST,     
-    CHORD_FS,          /* find_successor */
-    CHORD_FS_REPL,     /* find_successor reply */
-    CHORD_STAB,        /* get predecessor */
-    CHORD_STAB_REPL,   /* ... response */
-    CHORD_NOTIFY,      /* notify (predecessor) */
-    CHORD_PING,        /* are you alive? */
-    CHORD_PONG,        /* yes, I am */
-    CHORD_FINGERS_GET, /* get your finger list */
-    CHORD_FINGERS_REPL,/* .. here is my finger list */
-    CHORD_TRACEROUTE,  /* traceroute */
-    CHORD_TRACEROUTE_LAST,
-    CHORD_TRACEROUTE_REPL,/* traceroute repl */
-};
-
-/* XXX: warning: portability bugs */
-typedef uint8_t byte;
-typedef unsigned char  uchar;
-#ifdef __APPLE__
-typedef u_long ulong;
-#endif
-
-typedef struct {
-    byte x[ID_LEN];
-} chordID;
-
-#define KEY_LEN 20
-typedef struct {
-    char x[KEY_LEN];
-} Key;
-
-struct Node
-{
-    chordID id;
-    in_addr_t addr;
-    in_port_t port;
-};
-
-struct Finger
-{
-    Node node;          /* ID and address of finger */
-    int  status;        /* specifies whether this finger has been 
-                        * pinged; possible values: F_PASSIVE (the node
-                        * has not been pinged) and F_ACTIVE (the node
-                        * has been pinged) 
-                        */
-    int npings;         /* # of unanswered pings */
-    long rtt_avg;       /* average rtt to finger (ms in simulator, 
-                        * usec in the implementation)
-                        */
-    long rtt_dev;       /* rtt's mean deviation (ms in simulator, 
-                        * usec in the implementation)
-                        */
-                         /* rtt_avg, rtt_dev can be used to implement 
-                          * proximity routing or set up RTO for ping 
-                          */
-    struct Finger *next;
-    struct Finger *prev;
-};
-
-/* Finger table contains NFINGERS fingers, then predecessor, then
-   the successor list */
-
-struct Server
-{
-    Node node;          /* addr and ID */
-    Finger *head_flist; /* head and tail of finger  */
-    Finger *tail_flist; /* table + pred + successors 
-                        */
-    int to_fix_finger;  /* next finger to be fixed */
-    int to_fix_backup;  /* next successor/predecessor to be fixed */
-    int to_ping;        /* next node in finger list to be refreshed */
-    uint64_t next_stabilize_us;        /* value of wall_time() at next 
stabilize */
-
-    int in_sock;      /* incoming socket */
-    int out_sock;     /* outgoing socket */
-};
-
-#define PRED(srv)  (srv->tail_flist)
-#define SUCC(srv)  (srv->head_flist)
-
-/* GLOBALS */
-extern Node well_known[MAX_WELLKNOWN];
-extern int nknown;
-#define MAX_KEY_NUM 20
-/* the keys in KeyArray are read from file acclist.txt,
- * and are used to authenticate users sending control 
- * messages such as CHORD_FINGERS_GET.
- * This mechanism is intended to prevent trivial DDoS attacks.
- *
- * (For now the keyes are sent and stored in clear so
- *  the security provided by this mechanism is quite weak)
- */
-#define ACCLIST_FILE "acclist.txt"
-extern Key KeyArray[MAX_KEY_NUM];
-extern int NumKeys;
-
-/* chord.c */
-extern void chord_main(char *conf_file, int parent_sock);
-extern void initialize(Server *srv);
-extern void handle_packet(int network);
-extern int read_keys(char *file, Key *keyarray, int max_num_keys);
-
-/* finger.c */
-extern Finger *new_finger(Node *node);
-extern Finger *succ_finger(Server *srv);
-extern Finger *pred_finger(Server *srv);
-extern Finger *closest_preceding_finger(Server *srv, chordID *id, int fall);
-extern Node *closest_preceding_node(Server *srv, chordID *id, int fall);
-extern void remove_finger(Server *srv, Finger *f);
-extern Finger *get_finger(Server *srv, chordID *id);
-extern Finger *insert_finger(Server *srv, chordID *id, 
-                            in_addr_t addr, in_port_t port, int *fnew);
-void free_finger_list(Finger *flist);
-
-/* hosts.c */
-extern in_addr_t get_addr(void); /* get_addr: get IP address of server */
-
-/* join.c */
-extern void join(Server *srv, FILE *fp);
-
-/* pack.c */
-extern int dispatch(Server *srv, int n, uchar *buf);
-
-extern int pack(uchar *buf, char *fmt, ...);
-extern int unpack(uchar *buf, char *fmt, ...);
-extern int sizeof_fmt(char *fmt);
-
-#ifdef CCURED
-// These are the kinds of arguments that we pass to pack
-struct pack_args {
-  int f1;
-  chordID * f2;
-};
-#pragma ccuredvararg("pack", sizeof(struct pack_args))
-struct unpack_args {
-  ushort * f1;
-  uchar * f2;
-  ulong * f3;
-  chordID *id;
-};
-#pragma ccuredvararg("unpack", sizeof(struct unpack_args))
-#endif
-
-extern int pack_data(uchar *buf, uchar type, byte ttl, 
-                    chordID *id, ushort len, uchar *data);
-extern int unpack_data(Server *srv, int n, uchar *buf);
-extern int pack_fs(uchar *buf, byte ttl, chordID *id, ulong addr, ushort port);
-extern int unpack_fs(Server *srv, int n, uchar *buf);
-extern int pack_fs_repl(uchar *buf, chordID *id, ulong addr, ushort port);
-extern int unpack_fs_repl(Server *srv, int n, uchar *buf);
-extern int pack_stab(uchar *buf, chordID *id, ulong addr, ushort port);
-extern int unpack_stab(Server *srv, int n, uchar *buf);
-extern int pack_stab_repl(uchar *buf, chordID *id, ulong addr, ushort port);
-extern int unpack_stab_repl(Server *srv, int n, uchar *buf);
-extern int pack_notify(uchar *buf, chordID *id, ulong addr, ushort port);
-extern int unpack_notify(Server *srv, int n, uchar *buf);
-int pack_ping(uchar *buf, chordID *id, ulong addr, ushort port, ulong time);
-extern int unpack_ping(Server *srv, int n, uchar *buf);
-extern int pack_pong(uchar *buf, chordID *id, 
-                    ulong addr, ushort port, ulong time);
-extern int unpack_pong(Server *srv, int n, uchar *buf);
-extern int pack_fingers_get(uchar *buf, ulong addr, ushort port, Key *key);
-extern int unpack_fingers_get(Server *srv, int n, uchar *buf);
-extern int pack_fingers_repl(uchar *buf, Server *srv);
-extern int unpack_fingers_repl(Server *null, int n, uchar *buf);
-
-extern int pack_traceroute(uchar *buf, Server *srv, Finger *f, 
-                          uchar type, byte ttl, byte hops);
-extern int unpack_traceroute(Server *srv, int n, uchar *buf);
-extern int pack_traceroute_repl(uchar *buf, Server *srv, byte ttl, byte hops,
-                               ulong *paddr, ushort *pport, int one_hop);
-extern int unpack_traceroute_repl(Server *srv, int n, uchar *buf);
-
-/* process.c */
-extern int process_data(Server *srv, uchar type, byte ttl, chordID *id,  
-                       ushort len, uchar *data);
-extern int process_fs(Server *srv, byte ttl, 
-                     chordID *id, ulong addr, ushort port);
-extern int process_fs_repl(Server *srv, chordID *id, ulong addr, ushort port);
-extern int process_stab(Server *srv, chordID *id, ulong addr, ushort port);
-extern int process_stab_repl(Server *srv, chordID *id, 
-                            ulong addr, ushort port);
-extern int process_notify(Server *srv, chordID *id, ulong addr, ushort port);
-extern int process_ping(Server *srv, chordID *id,
-                       ulong addr, ushort port, ulong time);
-extern int process_pong(Server *srv, chordID *id, 
-                       ulong addr, ushort port, ulong time);
-extern int process_fingers_get(Server *srv, ulong addr, ushort port, Key *key);
-extern int process_fingers_repl(Server *srv, uchar ret_code);
-extern int process_traceroute(Server *srv, chordID *id, char *buf,
-                             uchar type, byte ttl, byte hops);
-extern int process_traceroute_repl(Server *srv, char *buf,
-                                  byte ttl, byte hops);
-
-/* sendpkt.c */
-extern void send_raw(Server *srv, in_addr_t addr, in_port_t port, 
-                    int n, uchar *buf);
-extern void send_data(Server *srv, uchar type, byte ttl, Node *np, 
-                     chordID *id, ushort n, uchar *data);
-extern void send_fs(Server *srv, byte ttl, ulong to_addr, ushort to_port,
-                   chordID *id, ulong addr, ushort port);
-extern void send_fs_repl(Server *srv, ulong to_addr, ushort to_port,
-                        chordID *id, ulong addr, ushort port);
-extern void send_stab(Server *srv, ulong to_addr, ushort to_port,
-                     chordID *id, ulong addr, ushort port);
-extern void send_stab_repl(Server *srv, ulong to_addr, ushort to_port,
-                          chordID *id, ulong addr, ushort port);
-extern void send_notify(Server *srv, ulong to_addr, ushort to_port,
-                       chordID *id, ulong addr, ushort port);
-extern void send_ping(Server *srv, ulong to_addr, ushort to_port,
-                     ulong addr, ushort port, ulong time);
-extern void send_pong(Server *srv, ulong to_addr, ushort to_port, ulong time);
-extern void send_fingers_get(Server *srv, ulong to_addr, ushort to_port,
-                            ulong addr, ushort port, Key *key);
-extern void send_fingers_repl(Server *srv, ulong to_addr, ushort to_port);
-extern void send_traceroute(Server *srv, Finger *f, uchar *buf, 
-                           uchar type, byte ttl, byte hops);
-extern void send_traceroute_repl(Server *srv, uchar *buf, int ttl, 
-                                int hops, int one_hop);
-
-/* stabilize.c */
-extern void stabilize(Server *srv);
-extern void set_stabilize_timer(void);
-
-/* api.c */
-extern int chord_init(char *conf_file);
-extern void chord_cleanup(int signum);
-extern void chord_route(chordID *k, char *data, int len);
-extern void chord_deliver(int n, uchar *data);
-extern void chord_get_range(chordID *l, chordID *r);
-void chord_update_range(chordID *l, chordID *r);
-int chord_is_local(chordID *x);
-
-/* util.c */
-extern ulong get_current_time(void);
-extern void update_rtt(long *rtt_avg, long *rtt_std, long new_rtt);
-extern chordID rand_ID(void);
-extern chordID successor(chordID id, int n);
-extern chordID predecessor(chordID id, int n);
-extern void add(chordID *a, chordID *b, chordID *res);
-extern void subtract(chordID *a, chordID *b, chordID *res);
-extern void random_between(chordID *a, chordID *b, chordID *res);
-extern int msb(chordID *x);
-extern int equals(chordID *a, chordID *b);
-extern int equals_id_str(chordID *a, char *b);
-extern int is_zero(chordID *x);
-extern int is_between(chordID *x, chordID *a, chordID *b);
-extern int copy_id( chordID *a, chordID *b);
-extern void print_id(FILE *f, chordID *id);
-extern chordID atoid(const char *str);
-extern unsigned hash(chordID *id, unsigned n);
-extern void print_chordID(chordID *id);
-extern void print_two_chordIDs(char *preffix, chordID *id1, 
-                              char *middle, chordID *id2, 
-                              char *suffix);
-extern void print_three_chordIDs(char *preffix, chordID *id1, 
-                                char *middle1, chordID *id2, 
-                                char *middle2, chordID *id3,
-                                char *suffix);
-extern void print_node(Node *node, char *prefix, char *suffix);
-extern void print_finger(Finger *f, char *prefix, char *suffix);
-extern void print_finger_list(Finger *fhead, char *prefix, char *suffix);
-extern void print_server(Server *s, char *prefix, char *suffix);
-extern void print_process(Server *srv, char *process_type, chordID *id,
-                         ulong addr, ushort port);
-extern void print_send(Server *srv, char *send_type, chordID *id,
-                      ulong addr, ushort port);
-extern void print_fun(Server *srv, char *fun_name, chordID *id);
-void print_current_time(char *prefix, char *suffix);
-extern int match_key(Key *key);
-
-#ifdef SIM_CHORD
-void sim_send_raw(Server *srv, 
-                 in_addr_t addr, in_port_t port, int n, uchar *buf);
-void sim_deliver_data(Server *srv, chordID *id, int n, uchar *data);
-Server *get_random_server(int no_idx, int status);
-int sim_chord_is_local(Server *srv, chordID *x);
-double sim_get_time(void);
-#endif
-
-#include "eprintf.h"
-
-#endif /* INCL_CHORD_H */
+#include <sys/types.h>
+#include <netinet/in.h>
+#ifdef __APPLE__
+#include <inttypes.h>  // Need uint64_t
+#endif
+#include <stdio.h>
+#include "debug.h"
+
+#ifndef INCL_CHORD_H
+#define INCL_CHORD_H
+
+typedef struct Finger Finger;
+typedef struct Node Node;
+typedef struct Server Server;
+
+
+#define NELEMS(a) (sizeof(a) / sizeof(a[0]))
+#ifndef FALSE
+#define FALSE 0
+#define TRUE  1
+#endif
+
+/* whether a finger is passive or active */
+#define F_PASSIVE 0
+#define F_ACTIVE  1
+
+//#define SIM_CHORD
+
+#ifdef SIM_CHORD
+enum {
+    NBITS            = 16,         /* # bits of an ID */
+    ID_LEN           = NBITS / 8,  /* bytes per ID */
+    NFINGERS         = NBITS,      /* # fingers per node */
+    NSUCCESSORS      = 3,          /* # successors kept */
+    NPREDECESSORS    = 3,          /* # predecessors kep */
+    BUFSIZE          = 65535,      /* buffer for packets */
+    STABILIZE_PERIOD = 1 * 1000000,  /* in usec  */
+    MAX_WELLKNOWN    = 4,          /* maximum number of "seed" servers */
+    MAX_SIMJOIN      = 4,          /* maximum number of servers
+                                    * contacted simultaneously when joining
+                                    */
+    PING_THRESH      = 3,          /* this many unanswered pings are allowed */
+    DEF_TTL          = 64,         /* default TTL for multi-hop packets */
+};
+#else
+enum {
+    NBITS            = 160,        /* # bits per ID, same as SHA-1 output */
+    ID_LEN           = NBITS / 8,  /* bytes per ID */
+    NFINGERS         = NBITS,      /* # fingers per node */
+    NSUCCESSORS      = 8,          /* # successors kept */
+    NPREDECESSORS    = 3,          /* # predecessors kept */
+    STABILIZE_PERIOD = 1 * 1000000,  /* in usec */
+    BUFSIZE          = 65535,      /* buffer for packets */
+    MAX_WELLKNOWN    = 50,         /* maximum number of other known servers
+                                    *  (read from configuration file)
+                                    */
+    MAX_SIMJOIN      = 4,          /* maximum number of servers
+                                    * contacted simultaneously when joining
+                                    */
+    PING_THRESH      = 5,          /* this many unanswered pings are allowed */
+    DEF_TTL          = 64,         /* default TTL for multi-hop packets */
+};
+#endif /* SIM_CHORD */
+
+/* packet types */
+enum {
+    CHORD_ROUTE = 0,   /* data packet */
+    CHORD_ROUTE_LAST,
+    CHORD_FS,          /* find_successor */
+    CHORD_FS_REPL,     /* find_successor reply */
+    CHORD_STAB,        /* get predecessor */
+    CHORD_STAB_REPL,   /* ... response */
+    CHORD_NOTIFY,      /* notify (predecessor) */
+    CHORD_PING,        /* are you alive? */
+    CHORD_PONG,        /* yes, I am */
+    CHORD_FINGERS_GET, /* get your finger list */
+    CHORD_FINGERS_REPL, /* .. here is my finger list */
+    CHORD_TRACEROUTE,  /* traceroute */
+    CHORD_TRACEROUTE_LAST,
+    CHORD_TRACEROUTE_REPL, /* traceroute repl */
+};
+
+/* XXX: warning: portability bugs */
+typedef uint8_t byte;
+typedef unsigned char uchar;
+#ifdef __APPLE__
+typedef u_long ulong;
+#endif
+
+typedef struct {
+    byte x[ID_LEN];
+} chordID;
+
+#define KEY_LEN 20
+typedef struct {
+    char x[KEY_LEN];
+} Key;
+
+struct Node {
+    chordID   id;
+    in_addr_t addr;
+    in_port_t port;
+};
+
+struct Finger {
+    Node node;          /* ID and address of finger */
+    int  status;        /* specifies whether this finger has been
+                         * pinged; possible values: F_PASSIVE (the node
+                         * has not been pinged) and F_ACTIVE (the node
+                         * has been pinged)
+                         */
+    int  npings;        /* # of unanswered pings */
+    long rtt_avg;       /* average rtt to finger (ms in simulator,
+                         * usec in the implementation)
+                         */
+    long rtt_dev;       /* rtt's mean deviation (ms in simulator,
+                         * usec in the implementation)
+                         */
+                        /* rtt_avg, rtt_dev can be used to implement
+                         * proximity routing or set up RTO for ping
+                         */
+    struct Finger *next;
+    struct Finger *prev;
+};
+
+/* Finger table contains NFINGERS fingers, then predecessor, then
+ * the successor list */
+
+struct Server {
+    Node     node;      /* addr and ID */
+    Finger * head_flist; /* head and tail of finger  */
+    Finger * tail_flist; /* table + pred + successors
+                          */
+    int      to_fix_finger; /* next finger to be fixed */
+    int      to_fix_backup; /* next successor/predecessor to be fixed */
+    int      to_ping;   /* next node in finger list to be refreshed */
+    uint64_t next_stabilize_us; /* value of wall_time() at next stabilize */
+
+    int      in_sock; /* incoming socket */
+    int      out_sock; /* outgoing socket */
+};
+
+#define PRED(srv)  (srv->tail_flist)
+#define SUCC(srv)  (srv->head_flist)
+
+/* GLOBALS */
+extern Node well_known[MAX_WELLKNOWN];
+extern int nknown;
+#define MAX_KEY_NUM 20
+/* the keys in KeyArray are read from file acclist.txt,
+ * and are used to authenticate users sending control
+ * messages such as CHORD_FINGERS_GET.
+ * This mechanism is intended to prevent trivial DDoS attacks.
+ *
+ * (For now the keyes are sent and stored in clear so
+ *  the security provided by this mechanism is quite weak)
+ */
+#define ACCLIST_FILE "acclist.txt"
+extern Key KeyArray[MAX_KEY_NUM];
+extern int NumKeys;
+
+/* chord.c */
+extern void chord_main(char *conf_file, int parent_sock);
+extern void initialize(Server *srv);
+extern void handle_packet(int network);
+extern int read_keys(char *file, Key *keyarray, int max_num_keys);
+
+/* finger.c */
+extern Finger *new_finger(Node *node);
+extern Finger *succ_finger(Server *srv);
+extern Finger *pred_finger(Server *srv);
+extern Finger *closest_preceding_finger(Server *srv, chordID *id, int fall);
+extern Node *closest_preceding_node(Server *srv, chordID *id, int fall);
+extern void remove_finger(Server *srv, Finger *f);
+extern Finger *get_finger(Server *srv, chordID *id);
+extern Finger *insert_finger(Server *srv, chordID *id,
+                             in_addr_t addr, in_port_t port, int *fnew);
+void free_finger_list(Finger *flist);
+
+/* hosts.c */
+extern in_addr_t get_addr(void); /* get_addr: get IP address of server */
+
+/* join.c */
+extern void join(Server *srv, FILE *fp);
+
+/* pack.c */
+extern int dispatch(Server *srv, int n, uchar *buf);
+
+extern int pack(uchar *buf, char *fmt, ...);
+extern int unpack(uchar *buf, char *fmt, ...);
+extern int sizeof_fmt(char *fmt);
+
+#ifdef CCURED
+// These are the kinds of arguments that we pass to pack
+struct pack_args {
+    int      f1;
+    chordID *f2;
+};
+#pragma ccuredvararg("pack", sizeof(struct pack_args))
+struct unpack_args {
+    ushort * f1;
+    uchar *  f2;
+    ulong *  f3;
+    chordID *id;
+};
+#pragma ccuredvararg("unpack", sizeof(struct unpack_args))
+#endif
+
+extern int pack_data(uchar *buf, uchar type, byte ttl,
+                     chordID *id, ushort len, uchar *data);
+extern int unpack_data(Server *srv, int n, uchar *buf);
+extern int pack_fs(uchar *buf, byte ttl, chordID *id, ulong addr, ushort port);
+extern int unpack_fs(Server *srv, int n, uchar *buf);
+extern int pack_fs_repl(uchar *buf, chordID *id, ulong addr, ushort port);
+extern int unpack_fs_repl(Server *srv, int n, uchar *buf);
+extern int pack_stab(uchar *buf, chordID *id, ulong addr, ushort port);
+extern int unpack_stab(Server *srv, int n, uchar *buf);
+extern int pack_stab_repl(uchar *buf, chordID *id, ulong addr, ushort port);
+extern int unpack_stab_repl(Server *srv, int n, uchar *buf);
+extern int pack_notify(uchar *buf, chordID *id, ulong addr, ushort port);
+extern int unpack_notify(Server *srv, int n, uchar *buf);
+int pack_ping(uchar *buf, chordID *id, ulong addr, ushort port, ulong time);
+extern int unpack_ping(Server *srv, int n, uchar *buf);
+extern int pack_pong(uchar *buf, chordID *id,
+                     ulong addr, ushort port, ulong time);
+extern int unpack_pong(Server *srv, int n, uchar *buf);
+extern int pack_fingers_get(uchar *buf, ulong addr, ushort port, Key *key);
+extern int unpack_fingers_get(Server *srv, int n, uchar *buf);
+extern int pack_fingers_repl(uchar *buf, Server *srv);
+extern int unpack_fingers_repl(Server *null, int n, uchar *buf);
+
+extern int pack_traceroute(uchar *buf, Server *srv, Finger *f,
+                           uchar type, byte ttl, byte hops);
+extern int unpack_traceroute(Server *srv, int n, uchar *buf);
+extern int pack_traceroute_repl(uchar *buf, Server *srv, byte ttl, byte hops,
+                                ulong *paddr, ushort *pport, int one_hop);
+extern int unpack_traceroute_repl(Server *srv, int n, uchar *buf);
+
+/* process.c */
+extern int process_data(Server *srv, uchar type, byte ttl, chordID *id,
+                        ushort len, uchar *data);
+extern int process_fs(Server *srv, byte ttl,
+                      chordID *id, ulong addr, ushort port);
+extern int process_fs_repl(Server *srv, chordID *id, ulong addr, ushort port);
+extern int process_stab(Server *srv, chordID *id, ulong addr, ushort port);
+extern int process_stab_repl(Server *srv, chordID *id,
+                             ulong addr, ushort port);
+extern int process_notify(Server *srv, chordID *id, ulong addr, ushort port);
+extern int process_ping(Server *srv, chordID *id,
+                        ulong addr, ushort port, ulong time);
+extern int process_pong(Server *srv, chordID *id,
+                        ulong addr, ushort port, ulong time);
+extern int process_fingers_get(Server *srv, ulong addr, ushort port, Key *key);
+extern int process_fingers_repl(Server *srv, uchar ret_code);
+extern int process_traceroute(Server *srv, chordID *id, char *buf,
+                              uchar type, byte ttl, byte hops);
+extern int process_traceroute_repl(Server *srv, char *buf,
+                                   byte ttl, byte hops);
+
+/* sendpkt.c */
+extern void send_raw(Server *srv, in_addr_t addr, in_port_t port,
+                     int n, uchar *buf);
+extern void send_data(Server *srv, uchar type, byte ttl, Node *np,
+                      chordID *id, ushort n, uchar *data);
+extern void send_fs(Server *srv, byte ttl, ulong to_addr, ushort to_port,
+                    chordID *id, ulong addr, ushort port);
+extern void send_fs_repl(Server *srv, ulong to_addr, ushort to_port,
+                         chordID *id, ulong addr, ushort port);
+extern void send_stab(Server *srv, ulong to_addr, ushort to_port,
+                      chordID *id, ulong addr, ushort port);
+extern void send_stab_repl(Server *srv, ulong to_addr, ushort to_port,
+                           chordID *id, ulong addr, ushort port);
+extern void send_notify(Server *srv, ulong to_addr, ushort to_port,
+                        chordID *id, ulong addr, ushort port);
+extern void send_ping(Server *srv, ulong to_addr, ushort to_port,
+                      ulong addr, ushort port, ulong time);
+extern void send_pong(Server *srv, ulong to_addr, ushort to_port, ulong time);
+extern void send_fingers_get(Server *srv, ulong to_addr, ushort to_port,
+                             ulong addr, ushort port, Key *key);
+extern void send_fingers_repl(Server *srv, ulong to_addr, ushort to_port);
+extern void send_traceroute(Server *srv, Finger *f, uchar *buf,
+                            uchar type, byte ttl, byte hops);
+extern void send_traceroute_repl(Server *srv, uchar *buf, int ttl,
+                                 int hops, int one_hop);
+
+/* stabilize.c */
+extern void stabilize(Server *srv);
+extern void set_stabilize_timer(void);
+
+/* api.c */
+extern int chord_init(char *conf_file);
+extern void chord_cleanup(int signum);
+extern void chord_route(chordID *k, char *data, int len);
+extern void chord_deliver(int n, uchar *data);
+extern void chord_get_range(chordID *l, chordID *r);
+void chord_update_range(chordID *l, chordID *r);
+int chord_is_local(chordID *x);
+
+/* util.c */
+extern ulong get_current_time(void);
+extern void update_rtt(long *rtt_avg, long *rtt_std, long new_rtt);
+extern chordID rand_ID(void);
+extern chordID successor(chordID id, int n);
+extern chordID predecessor(chordID id, int n);
+extern void add(chordID *a, chordID *b, chordID *res);
+extern void subtract(chordID *a, chordID *b, chordID *res);
+extern void random_between(chordID *a, chordID *b, chordID *res);
+extern int msb(chordID *x);
+extern int equals(chordID *a, chordID *b);
+extern int equals_id_str(chordID *a, char *b);
+extern int is_zero(chordID *x);
+extern int is_between(chordID *x, chordID *a, chordID *b);
+extern int copy_id( chordID *a, chordID *b);
+extern void print_id(FILE *f, chordID *id);
+extern chordID atoid(const char *str);
+extern unsigned hash(chordID *id, unsigned n);
+extern void print_chordID(chordID *id);
+extern void print_two_chordIDs(char *preffix, chordID *id1,
+                               char *middle, chordID *id2,
+                               char *suffix);
+extern void print_three_chordIDs(char *preffix, chordID *id1,
+                                 char *middle1, chordID *id2,
+                                 char *middle2, chordID *id3,
+                                 char *suffix);
+extern void print_node(Node *node, char *prefix, char *suffix);
+extern void print_finger(Finger *f, char *prefix, char *suffix);
+extern void print_finger_list(Finger *fhead, char *prefix, char *suffix);
+extern void print_server(Server *s, char *prefix, char *suffix);
+extern void print_process(Server *srv, char *process_type, chordID *id,
+                          ulong addr, ushort port);
+extern void print_send(Server *srv, char *send_type, chordID *id,
+                       ulong addr, ushort port);
+extern void print_fun(Server *srv, char *fun_name, chordID *id);
+void print_current_time(char *prefix, char *suffix);
+extern int match_key(Key *key);
+
+#ifdef SIM_CHORD
+void sim_send_raw(Server *srv,
+                  in_addr_t addr, in_port_t port, int n, uchar *buf);
+void sim_deliver_data(Server *srv, chordID *id, int n, uchar *data);
+Server *get_random_server(int no_idx, int status);
+int sim_chord_is_local(Server *srv, chordID *x);
+double sim_get_time(void);
+#endif
+
+#include "eprintf.h"
+
+#endif /* INCL_CHORD_H */

=== modified file 'i3/chord/chord_api.h'
--- i3/chord/chord_api.h        2009-12-11 22:49:11 +0000
+++ i3/chord/chord_api.h        2010-02-11 11:49:47 +0000
@@ -1,26 +1,26 @@
-#ifndef _CHORD_API_H
-#define _CHORD_API_H
-
-typedef unsigned char byte;
-
-enum {
-  CHORD_ID_BITS = 160,
-};
-
-typedef struct {
-    byte x[CHORD_ID_BITS/8];
-} chordID;
-
-/* init: initialize chord server, provide configuration file */
-int chord_init(char *conf_file);
-
-/* route: forward message M towards the root of key K. */
-void chord_route(chordID *k, char *data, int len);
-
-/* get_range: returns the range (l,r] that this node is responsible for */
-void chord_get_range(chordID *l, chordID *r);
-
-/* is_local: Does this ID belong to this server? */
-int chord_is_local(chordID *x);
-
-#endif
+#ifndef _CHORD_API_H
+#define _CHORD_API_H
+
+typedef unsigned char byte;
+
+enum {
+    CHORD_ID_BITS = 160,
+};
+
+typedef struct {
+    byte x[CHORD_ID_BITS / 8];
+} chordID;
+
+/* init: initialize chord server, provide configuration file */
+int chord_init(char *conf_file);
+
+/* route: forward message M towards the root of key K. */
+void chord_route(chordID *k, char *data, int len);
+
+/* get_range: returns the range (l,r] that this node is responsible for */
+void chord_get_range(chordID *l, chordID *r);
+
+/* is_local: Does this ID belong to this server? */
+int chord_is_local(chordID *x);
+
+#endif

=== modified file 'i3/chord/chord_getfingers.c'
--- i3/chord/chord_getfingers.c 2009-12-11 22:49:11 +0000
+++ i3/chord/chord_getfingers.c 2010-02-11 11:49:47 +0000
@@ -5,11 +5,11 @@
  *  node_IP_addr, port - IP address and the port number of a Chord node
  *  -all - if this parameter is specified, the command displays
  *         the information about each node in the system. Otherwise, it
- *         displays only the information about the Chord node whose 
+ *         displays only the information about the Chord node whose
  *         address and port number are specified in the command line.
  *
- *         The node-related information includes its finger list. Associated 
- *         to each finger, the command displays the mean value and standard 
+ *         The node-related information includes its finger list. Associated
+ *         to each finger, the command displays the mean value and standard
  *         deviation of the round-trip-time.
  *
  *  Note: This command doesn't work behind NATs and firewalls.
@@ -39,158 +39,168 @@
 
 
 typedef struct iditem_ {
-  chordID id;
-  struct iditem_ *next;
+    chordID         id;
+    struct iditem_ *next;
 } IDitem;
 
-static int unpack_print_getnext(char *buf, int n, ulong *succ_addr, 
-                               ushort *succ_port);
+static int unpack_print_getnext(char *buf, int n, ulong *succ_addr,
+                                ushort *succ_port);
 static IDitem *add_chordID(IDitem *head, chordID *id);
 static int find_chordID(IDitem *head, chordID *id);
-static int recv_packet(int in_sock, fd_set fdset, int nfds, 
-                      char *buf, int buf_len,
-                      ulong chordsrv_addr, ulong chordsrv_port);
+static int recv_packet(int in_sock, fd_set fdset, int nfds,
+                       char *buf, int buf_len,
+                       ulong chordsrv_addr, ulong chordsrv_port);
 
-int main(int argc, char *argv[]) 
+int main(int argc, char *argv[])
 {
-  Key    key;
-  int    in_sock, out_sock, len, rc;
-  int    argc_idx = 0, flag_all = FALSE;
-  ulong  chordsrv_addr, client_addr;
-  ushort chordsrv_port, client_port;
-  struct sockaddr_in chordsrv;
-  struct sockaddr_in sin, sout;
-  struct hostent *h;
-  fd_set fdset;
-  int    nfds;
-  int    retries = 0;
-  byte buf[BUFSIZE];
+    Key key;
+    int in_sock, out_sock, len, rc;
+    int argc_idx = 0, flag_all = FALSE;
+    ulong chordsrv_addr, client_addr;
+    ushort chordsrv_port, client_port;
+    struct sockaddr_in chordsrv;
+    struct sockaddr_in sin, sout;
+    struct hostent *h;
+    fd_set fdset;
+    int nfds;
+    int retries = 0;
+    byte buf[BUFSIZE];
 //  chordID id;
 
-  /* check command line args */
-  if(argc < 3) 
-    eprintf("usage: %s [-all] <node_IP_addr> <port>\n", argv[0]);
-
-  if (argc == 4) {
-    if (strcmp(argv[1], "-all")) {
-      eprintf("usage: %s [-all] <node_IP_addr> <port>\n", argv[0]);
-    } else {
-      argc_idx++;
-      flag_all = TRUE;
-    }
-  }
-
-  /* i3 server address and port number */
-  h = gethostbyname(argv[argc_idx+1]);
-  if(h==NULL) {
-    printf("%s: unknown host '%s' \n", argv[0], argv[argc_idx+1]);
-    exit(1);
-  }
-  assert(h->h_length == sizeof(long));
-  memcpy((char *) &chordsrv_addr, h->h_addr_list[0], h->h_length);
-  chordsrv_addr = ntohl(chordsrv_addr);
-  chordsrv_port = (ushort)atoi(argv[argc_idx+2]);
-
-  /* get client's address */
-  client_addr = ntohl(get_addr());
-  client_port = CLIENT_PORT;
-
-  /* create socket to receieve packets */
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_family = AF_INET;
-  sin.sin_port = htons(client_port);
-  sin.sin_addr.s_addr = htonl(INADDR_ANY);
-  
-  in_sock = socket(AF_INET, SOCK_DGRAM, 0);
-  if (in_sock < 0)
-    eprintf("incoming socket failed:");
-  if (bind(in_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0)
-    eprintf("bind to incoming socket failed:");
-  
-  /* create outgoing socket */ //  struct  in_addr ia;
-
-  memset(&sout, 0, sizeof(sout));
-  sout.sin_family = AF_INET;
-  sout.sin_port = htons(0);
-  sout.sin_addr.s_addr = htonl(INADDR_ANY);
-  out_sock = socket(AF_INET, SOCK_DGRAM, 0);
-  if (out_sock < 0) 
-    eprintf("outgoing socket failed:");
-  if (bind(out_sock, (struct sockaddr *) &sout, sizeof(sout)) < 0)
-    eprintf("bind to outgoing socket failed:");
-  
-  /* create CHORD_FINGERS_GET message */
-  rc = read_keys(KEY_FILE, &key, 1); 
-  if (rc < 1) {
-    close(in_sock);;
+    /* check command line args */
+    if (argc < 3) {
+        eprintf("usage: %s [-all] <node_IP_addr> <port>\n", argv[0]);
+    }
+
+    if (argc == 4) {
+        if (strcmp(argv[1], "-all")) {
+            eprintf("usage: %s [-all] <node_IP_addr> <port>\n", argv[0]);
+        } else {
+            argc_idx++;
+            flag_all = TRUE;
+        }
+    }
+
+    /* i3 server address and port number */
+    h = gethostbyname(argv[argc_idx + 1]);
+    if (h == NULL) {
+        printf("%s: unknown host '%s' \n", argv[0], argv[argc_idx + 1]);
+        exit(1);
+    }
+    assert(h->h_length == sizeof(long));
+    memcpy((char *) &chordsrv_addr, h->h_addr_list[0], h->h_length);
+    chordsrv_addr       = ntohl(chordsrv_addr);
+    chordsrv_port       = (ushort) atoi(argv[argc_idx + 2]);
+
+    /* get client's address */
+    client_addr         = ntohl(get_addr());
+    client_port         = CLIENT_PORT;
+
+    /* create socket to receieve packets */
+    memset(&sin, 0, sizeof(sin));
+    sin.sin_family      = AF_INET;
+    sin.sin_port        = htons(client_port);
+    sin.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    in_sock             = socket(AF_INET, SOCK_DGRAM, 0);
+    if (in_sock < 0) {
+        eprintf("incoming socket failed:");
+    }
+    if (bind(in_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+        eprintf("bind to incoming socket failed:");
+    }
+
+    /* create outgoing socket */ //  struct  in_addr ia;
+
+    memset(&sout, 0, sizeof(sout));
+    sout.sin_family      = AF_INET;
+    sout.sin_port        = htons(0);
+    sout.sin_addr.s_addr = htonl(INADDR_ANY);
+    out_sock             = socket(AF_INET, SOCK_DGRAM, 0);
+    if (out_sock < 0) {
+        eprintf("outgoing socket failed:");
+    }
+    if (bind(out_sock, (struct sockaddr *) &sout, sizeof(sout)) < 0) {
+        eprintf("bind to outgoing socket failed:");
+    }
+
+    /* create CHORD_FINGERS_GET message */
+    rc = read_keys(KEY_FILE, &key, 1);
+    if (rc < 1) {
+        close(in_sock);
+        ;
+        close(out_sock);
+        if (rc == -1) {
+            eprintf("Error opening file: %s\n", KEY_FILE);
+        }
+        if (rc == 0) {
+            eprintf("No key found in %s\n", KEY_FILE);
+        }
+    }
+
+    len                      = pack_fingers_get(buf, client_addr, client_port, 
&key);
+
+    chordsrv.sin_family      = h->h_addrtype;
+    chordsrv.sin_addr.s_addr = htonl(chordsrv_addr);
+    chordsrv.sin_port        = htons(chordsrv_port);
+
+    FD_ZERO(&fdset);
+    FD_SET(in_sock, &fdset);
+    nfds                     = in_sock + 1;
+
+    for (;; ) {
+        /* send CHORD_FINGERS_GET request */
+        len = pack_fingers_get(buf, client_addr, client_port, &key);
+        rc  = sendto(out_sock, buf, len, 0,
+                     (struct sockaddr *) &chordsrv, sizeof(chordsrv));
+        if (rc < 0) {
+            eprintf("cannot send data, errno: %d \n", errno);
+            break;
+        }
+        len = recv_packet(in_sock, fdset, nfds, (char *) buf, sizeof(buf),
+                          chordsrv_addr, chordsrv_port);
+
+        /* len == -1 -> no answer; the chord node is either done, or
+         * the message has been lost, or the acclist.txt is missing
+         * at the chord node or it doesn't contain the proper key
+         */
+        if (len == -1 && retries < MAX_RETRIES) {
+            retries++;
+            continue;
+        }
+        if (len == -1) {
+            /* no answer has been received from the chord node
+             * after MAX_RETRIES retries
+             */
+            printf("... giving up...\n");
+            printf("\nAlso, check whether file %s exists at the chord node,\n",
+                   ACCLIST_FILE);
+            printf("and if does, check whether it contains the key in %s\n",
+                   KEY_FILE);
+            printf("(see README for details).\n");
+            break;
+        }
+        if (unpack_print_getnext((char *) buf, len, &chordsrv_addr, 
&chordsrv_port)) {
+            chordsrv.sin_addr.s_addr = htonl(chordsrv_addr);
+            chordsrv.sin_port        = htons(chordsrv_port);
+            retries                  = 0;
+            if (flag_all == FALSE) {
+                break;
+            }
+        } else {
+            break;
+        }
+    }
+
+    close(in_sock);
+    ;
     close(out_sock);
-    if (rc == -1) 
-      eprintf("Error opening file: %s\n", KEY_FILE);
-    if (rc == 0) 
-      eprintf("No key found in %s\n", KEY_FILE);
-  }
-
-  len = pack_fingers_get(buf, client_addr, client_port, &key);
-
-  chordsrv.sin_family = h->h_addrtype;
-  chordsrv.sin_addr.s_addr = htonl(chordsrv_addr); 
-  chordsrv.sin_port = htons(chordsrv_port);
-
-  FD_ZERO(&fdset);
-  FD_SET(in_sock, &fdset);
-  nfds = in_sock + 1;
-
-  for (;;) {
-    /* send CHORD_FINGERS_GET request */
-    len = pack_fingers_get(buf, client_addr, client_port, &key);
-    rc = sendto(out_sock, buf, len, 0, 
-               (struct sockaddr *)&chordsrv, sizeof(chordsrv));
-    if(rc < 0) {
-      eprintf("cannot send data, errno: %d \n", errno);
-      break;
-    }    
-    len = recv_packet(in_sock, fdset, nfds, (char *)buf, sizeof(buf),
-                     chordsrv_addr, chordsrv_port);
-
-    /* len == -1 -> no answer; the chord node is either done, or
-     * the message has been lost, or the acclist.txt is missing
-     * at the chord node or it doesn't contain the proper key 
-     */
-    if (len == -1 && retries < MAX_RETRIES) {
-      retries++;
-      continue;
-    }
-    if (len == -1) {
-      /* no answer has been received from the chord node 
-       * after MAX_RETRIES retries 
-       */
-      printf("... giving up...\n");
-      printf("\nAlso, check whether file %s exists at the chord node,\n",
-            ACCLIST_FILE); 
-      printf("and if does, check whether it contains the key in %s\n",
-            KEY_FILE);
-      printf("(see README for details).\n");
-      break;
-    }
-    if (unpack_print_getnext((char *)buf, len, &chordsrv_addr, 
&chordsrv_port)) {
-      chordsrv.sin_addr.s_addr = htonl(chordsrv_addr); 
-      chordsrv.sin_port = htons(chordsrv_port);
-      retries = 0;
-      if (flag_all == FALSE)
-       break;
-    } else
-      break;
-  }
-
-  close(in_sock);;
-  close(out_sock);
-  printf("\n");
-
-  return 1;
+    printf("\n");
+
+    return 1;
 }
 
-
-/* this function unpacks the CHORD_FINGERS_REPL message 
+/* this function unpacks the CHORD_FINGERS_REPL message
  * and prints its content
  *
  * the function returns TRUE if the successor of the Chord node
@@ -198,125 +208,128 @@
  * the functions also returns the successor address and port
  * number in succ_addr and succ_port variables
  */
-static int unpack_print_getnext(char *buf, int n, 
-                               ulong *succ_addr, ushort *succ_port)
+static int unpack_print_getnext(char *buf, int n,
+                                ulong *succ_addr, ushort *succ_port)
 {
-  chordID id;
-  char    type;
-  ulong   addr, rtt_avg, rtt_dev;
-  ushort  port, npings;
-  int     len, i, ret_code;
-  struct  in_addr ia;
-  static IDitem *head_list = NULL;
-
-  len = unpack((uchar *)buf, "cxls", &type, &id, (ulong*)&addr, 
(ushort*)&port);
-  assert(type == CHORD_FINGERS_REPL);
-
-  if (find_chordID(head_list, &id) == TRUE) {
-    return FALSE;
-  } else {
-    head_list = add_chordID(head_list, &id);
-  }
-  printf("\nID=("); print_chordID(&id);
-  ia.s_addr = htonl(addr);
-  printf("), addr=(%s:%d)\n", inet_ntoa(ia), port);
-
-  if (len >= n-1) 
-    return FALSE;
-
-  i = 0;
-  do {
-    len += unpack((uchar*)(buf + len), "xlslls", &id, &addr, &port, 
-                 &rtt_avg, &rtt_dev, &npings);
-
-    *succ_addr = addr;
-    *succ_port = port;
-
-    printf("  F[%d]: ID=(", i++); print_chordID(&id);
+    chordID id;
+    char type;
+    ulong addr, rtt_avg, rtt_dev;
+    ushort port, npings;
+    int len, i, ret_code;
+    struct  in_addr ia;
+    static IDitem *head_list = NULL;
+
+    len = unpack((uchar *) buf, "cxls", &type, &id, (ulong *) &addr, (ushort 
*) &port);
+    assert(type == CHORD_FINGERS_REPL);
+
+    if (find_chordID(head_list, &id) == TRUE) {
+        return FALSE;
+    } else {
+        head_list = add_chordID(head_list, &id);
+    }
+    printf("\nID=(");
+    print_chordID(&id);
     ia.s_addr = htonl(addr);
     printf("), addr=(%s:%d)\n", inet_ntoa(ia), port);
-    printf("        rtt_avg = %5.2f ms, rtt_stdev = %5.2f ms\n",
-          (float)rtt_avg/1000., (float)rtt_dev/1000.);
-
-  } while (len + 1 < n);
-
-  if (len+1 > n) 
-    return FALSE;
-  
-  unpack((uchar*)(buf + len), "c", &ret_code);
-  return TRUE;
+
+    if (len >= n - 1) {
+        return FALSE;
+    }
+
+    i = 0;
+    do {
+        len       += unpack((uchar *) (buf + len), "xlslls", &id, &addr, &port,
+                            &rtt_avg, &rtt_dev, &npings);
+
+        *succ_addr = addr;
+        *succ_port = port;
+
+        printf("  F[%d]: ID=(", i++);
+        print_chordID(&id);
+        ia.s_addr  = htonl(addr);
+        printf("), addr=(%s:%d)\n", inet_ntoa(ia), port);
+        printf("        rtt_avg = %5.2f ms, rtt_stdev = %5.2f ms\n",
+               (float) rtt_avg / 1000., (float) rtt_dev / 1000.);
+    } while (len + 1 < n);
+
+    if (len + 1 > n) {
+        return FALSE;
+    }
+
+    unpack((uchar *) (buf + len), "c", &ret_code);
+    return TRUE;
 }
 
 static IDitem *add_chordID(IDitem *head, chordID *id)
 {
-  IDitem *item;
-
-  if ((item = calloc(1, sizeof(IDitem))) == NULL) {
-    eprintf("memory allocation error\n");
-  } else 
-    copy_id(&item->id, id);
-    
-  item->next = head;
-  return item;
+    IDitem *item;
+
+    if ((item = calloc(1, sizeof(IDitem))) == NULL) {
+        eprintf("memory allocation error\n");
+    } else {
+        copy_id(&item->id, id);
+    }
+
+    item->next = head;
+    return item;
 }
 
-
-/* search a chord ID in the list; use linear search 
+/* search a chord ID in the list; use linear search
  * for now--should change it later...
  */
 static int find_chordID(IDitem *head, chordID *id)
 {
-  IDitem *item = head;
+    IDitem *item = head;
 
-  for (; item; item = item->next) {
-    if (equals(&item->id, id))
-      return TRUE;
-  }
-  return FALSE;
+    for (; item; item = item->next) {
+        if (equals(&item->id, id)) {
+            return TRUE;
+        }
+    }
+    return FALSE;
 }
 
-
-static int recv_packet(int in_sock, fd_set fdset, int nfds, 
-                      char *buf, int buf_len,
-                      ulong chordsrv_addr, ulong chordsrv_port)
+static int recv_packet(int in_sock, fd_set fdset, int nfds,
+                       char *buf, int buf_len,
+                       ulong chordsrv_addr, ulong chordsrv_port)
 {
-  fd_set readset;
-  int    nfound, from_len, len;
-  struct timeval timeout;
-  struct sockaddr_in from;
-
-  for (;;) {
-    readset = fdset;
-    /* set a timeout in case we cannot contact the Chord node */
-    timeout.tv_sec = SELECT_TIMEOUT;
-    timeout.tv_usec = 0;
-    nfound = select(nfds, &readset, NULL, NULL, &timeout);
-
-    if (nfound < 0 && errno == EINTR) {
-      continue;
-    }
-    if (nfound == 0) {
-      /* timeout expired */
-      struct  in_addr ia;
-      ia.s_addr = htonl(chordsrv_addr);
-      printf("\nCouldn't contact node (%s:%d), try again...\n", 
-            inet_ntoa(ia), (int)chordsrv_port);
-      return -1;
-    }
-    if (FD_ISSET(in_sock, &readset)) {
-      /* this is the reply from the Chord node */
-      from_len = sizeof(from);
-      len = recvfrom(in_sock, buf, buf_len, 0,
-                      (struct sockaddr *)&from, (uint*)&from_len);
-      if (len < 0) {
-       if (errno != EAGAIN) {
-         printf("recvfrom failed.");  
-         continue;
-       }
-       weprintf("try again...");
-       continue;   
-      }
-      return len;
-    }
-  }
+    fd_set readset;
+    int nfound, from_len, len;
+    struct timeval timeout;
+    struct sockaddr_in from;
+
+    for (;; ) {
+        readset         = fdset;
+        /* set a timeout in case we cannot contact the Chord node */
+        timeout.tv_sec  = SELECT_TIMEOUT;
+        timeout.tv_usec = 0;
+        nfound          = select(nfds, &readset, NULL, NULL, &timeout);
+
+        if (nfound < 0 && errno == EINTR) {
+            continue;
+        }
+        if (nfound == 0) {
+            /* timeout expired */
+            struct  in_addr ia;
+            ia.s_addr = htonl(chordsrv_addr);
+            printf("\nCouldn't contact node (%s:%d), try again...\n",
+                   inet_ntoa(ia), (int) chordsrv_port);
+            return -1;
+        }
+        if (FD_ISSET(in_sock, &readset)) {
+            /* this is the reply from the Chord node */
+            from_len = sizeof(from);
+            len      = recvfrom(in_sock, buf, buf_len, 0,
+                                (struct sockaddr *) &from, (uint *) &from_len);
+            if (len < 0) {
+                if (errno != EAGAIN) {
+                    printf("recvfrom failed.");
+                    continue;
+                }
+                weprintf("try again...");
+                continue;
+            }
+            return len;
+        }
+    }
 }

=== modified file 'i3/chord/chord_traceroute.c'
--- i3/chord/chord_traceroute.c 2009-12-11 22:49:11 +0000
+++ i3/chord/chord_traceroute.c 2010-02-11 11:49:47 +0000
@@ -6,9 +6,9 @@
  *  node_IP_addr, port - IP address and the port number of a Chord node
  *        from where we originate the traceroute
  *
- *        This command dispalys the chord route to the node that is 
+ *        This command dispalys the chord route to the node that is
  *        responsibe for target ID (id) starting from the originator node.
- *        
+ *
  *  Note: This command doesn't work behind NATs and firewalls.
  */
 
@@ -36,158 +36,165 @@
 
 
 typedef struct iditem_ {
-  chordID id;
-  struct iditem_ *next;
+    chordID         id;
+    struct iditem_ *next;
 } IDitem;
 
-/*static int unpack_print_getnext(char *buf, int n, ulong *succ_addr, 
-                               ushort *succ_port);*/
+/*static int unpack_print_getnext(char *buf, int n, ulong *succ_addr,
+ *                              ushort *succ_port);*/
 /*static IDitem *add_chordID(IDitem *head, chordID *id);*/
 /*static int find_chordID(IDitem *head, chordID *id);*/
-static int recv_packet(int in_sock, fd_set fdset, int nfds, 
-                      char *buf, int buf_len,
-                      ulong chordsrv_addr, ulong chordsrv_port);
-static int pack_client_traceroute(uchar *buf, byte ttl, chordID *id, 
-                                 ulong client_addr, ushort client_port);
+static int recv_packet(int in_sock, fd_set fdset, int nfds,
+                       char *buf, int buf_len,
+                       ulong chordsrv_addr, ulong chordsrv_port);
+static int pack_client_traceroute(uchar *buf, byte ttl, chordID *id,
+                                  ulong client_addr, ushort client_port);
 static int unpack_client_traceroute_repl(char *buf, int n, int orig_ttl,
-                                        ulong chordsrv_addr, 
-                                        ushort chordsrv_port);
+                                         ulong chordsrv_addr,
+                                         ushort chordsrv_port);
 
-int main(int argc, char *argv[]) 
+int main(int argc, char *argv[])
 {
-  Key    key;
-  int    in_sock, out_sock, len, rc;
-  ulong  chordsrv_addr, client_addr;
-  ushort chordsrv_port, client_port;
-  struct sockaddr_in chordsrv;
-  struct sockaddr_in sin, sout;
-  struct hostent *h;
-  uchar  ttl = 1;
-  fd_set fdset;
-  int    nfds, i;
-  int    retries = 0;
-  byte buf[BUFSIZE];
-  chordID id;
-
-  /* check command line args */
-  if (argc != 4) 
-    eprintf("usage: %s <id> <node_IP_addr> <port>\n", argv[0]);
-
-  for (i = 0; i < ID_LEN; i++) {
-    char tmp[3];
+    Key key;
+    int in_sock, out_sock, len, rc;
+    ulong chordsrv_addr, client_addr;
+    ushort chordsrv_port, client_port;
+    struct sockaddr_in chordsrv;
+    struct sockaddr_in sin, sout;
+    struct hostent *h;
+    uchar ttl   = 1;
+    fd_set fdset;
+    int nfds, i;
+    int retries = 0;
+    byte buf[BUFSIZE];
+    chordID id;
+
+    /* check command line args */
+    if (argc != 4) {
+        eprintf("usage: %s <id> <node_IP_addr> <port>\n", argv[0]);
+    }
+
+    for (i = 0; i < ID_LEN; i++) {
+        char tmp[3];
 //    char  t;
 
-    tmp[0] = argv[1][2*i]; 
-    tmp[1] = argv[1][2*i+1]; 
-    tmp[2] = 0;
-    sscanf(tmp, "%x", (uint *)&id.x[i]);
-  }
-
-  /* chord server address and port number */
-  h = gethostbyname(argv[2]);
-  if(h==NULL) {
-    printf("%s: unknown host '%s' \n", argv[0], argv[2]);
-    exit(1);
-  }
-  assert(h->h_length == sizeof(long));
-  memcpy((char *) &chordsrv_addr, h->h_addr_list[0], h->h_length);
-  chordsrv_addr = ntohl(chordsrv_addr);
-  chordsrv_port = (ushort)atoi(argv[3]);
-
-  /* get client's address */
-  client_addr = ntohl(get_addr());
-  client_port = CLIENT_PORT;
-
-  /* create socket to receieve packets */
-  memset(&sin, 0, sizeof(sin));
-  sin.sin_family = AF_INET;
-  sin.sin_port = htons(client_port);
-  sin.sin_addr.s_addr = htonl(INADDR_ANY);
-  
-  in_sock = socket(AF_INET, SOCK_DGRAM, 0);
-  if (in_sock < 0)
-    eprintf("incoming socket failed:");
-  if (bind(in_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0)
-    eprintf("bind to incoming socket failed:");
-  
-  /* create outgoing socket */ // struct  in_addr ia;
-
-  memset(&sout, 0, sizeof(sout));
-  sout.sin_family = AF_INET;
-  sout.sin_port = htons(0);
-  sout.sin_addr.s_addr = htonl(INADDR_ANY);
-  out_sock = socket(AF_INET, SOCK_DGRAM, 0);
-  if (out_sock < 0)
-    eprintf("outgoing socket failed:");
-  if (bind(out_sock, (struct sockaddr *) &sout, sizeof(sout)) < 0)
-    eprintf("bind to outgoing socket failed:");
-
-  
-  /* create CHORD_FINGERS_GET message */
-  rc = read_keys(KEY_FILE, &key, 1); 
-  if (rc < 1) {
-    close(in_sock);;
+        tmp[0] = argv[1][2 * i];
+        tmp[1] = argv[1][2 * i + 1];
+        tmp[2] = 0;
+        sscanf(tmp, "%x", (uint *) &id.x[i]);
+    }
+
+    /* chord server address and port number */
+    h = gethostbyname(argv[2]);
+    if (h == NULL) {
+        printf("%s: unknown host '%s' \n", argv[0], argv[2]);
+        exit(1);
+    }
+    assert(h->h_length == sizeof(long));
+    memcpy((char *) &chordsrv_addr, h->h_addr_list[0], h->h_length);
+    chordsrv_addr       = ntohl(chordsrv_addr);
+    chordsrv_port       = (ushort) atoi(argv[3]);
+
+    /* get client's address */
+    client_addr         = ntohl(get_addr());
+    client_port         = CLIENT_PORT;
+
+    /* create socket to receieve packets */
+    memset(&sin, 0, sizeof(sin));
+    sin.sin_family      = AF_INET;
+    sin.sin_port        = htons(client_port);
+    sin.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    in_sock             = socket(AF_INET, SOCK_DGRAM, 0);
+    if (in_sock < 0) {
+        eprintf("incoming socket failed:");
+    }
+    if (bind(in_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+        eprintf("bind to incoming socket failed:");
+    }
+
+    /* create outgoing socket */ // struct  in_addr ia;
+
+    memset(&sout, 0, sizeof(sout));
+    sout.sin_family      = AF_INET;
+    sout.sin_port        = htons(0);
+    sout.sin_addr.s_addr = htonl(INADDR_ANY);
+    out_sock             = socket(AF_INET, SOCK_DGRAM, 0);
+    if (out_sock < 0) {
+        eprintf("outgoing socket failed:");
+    }
+    if (bind(out_sock, (struct sockaddr *) &sout, sizeof(sout)) < 0) {
+        eprintf("bind to outgoing socket failed:");
+    }
+
+
+    /* create CHORD_FINGERS_GET message */
+    rc = read_keys(KEY_FILE, &key, 1);
+    if (rc < 1) {
+        close(in_sock);
+        ;
+        close(out_sock);
+        if (rc == -1) {
+            eprintf("Error opening file: %s\n", KEY_FILE);
+        }
+        if (rc == 0) {
+            eprintf("No key found in %s\n", KEY_FILE);
+        }
+    }
+    len                      = pack_fingers_get(buf, client_addr, client_port, 
&key);
+
+    chordsrv.sin_family      = h->h_addrtype;
+    chordsrv.sin_addr.s_addr = htonl(chordsrv_addr);
+    chordsrv.sin_port        = htons(chordsrv_port);
+
+    FD_ZERO(&fdset);
+    FD_SET(in_sock, &fdset);
+    nfds                     = in_sock + 1;
+
+    for (;; ) {
+        /* send CHORD_FINGERS_GET request */
+        len = pack_client_traceroute(buf, ttl, &id, client_addr, client_port);
+        rc  = sendto(out_sock, buf, len, 0,
+                     (struct sockaddr *) &chordsrv, sizeof(chordsrv));
+        if (rc < 0) {
+            printf("cannot send data, errno: %d \n", errno);
+            return -1;
+        }
+
+        len = recv_packet(in_sock, fdset, nfds, (char *) buf, sizeof(buf),
+                          chordsrv_addr, chordsrv_port);
+
+        if (len == -1 && retries < MAX_RETRIES) {
+            retries++;
+            continue;
+        }
+        if (len == -1 ||
+            (!unpack_client_traceroute_repl((char *) buf, len, ttl,
+                                            chordsrv_addr, chordsrv_port))) {
+            if (len == -1) {
+                printf("... giving up...\n");
+                printf("\nAlso, check whether file %s exists at the chord 
node,\n",
+                       ACCLIST_FILE);
+                printf("and if does, check whether it contains the key in 
%s\n",
+                       KEY_FILE);
+                printf("(see README for details).\n");
+            }
+            break;
+        } else {
+            retries = 0;
+            ttl++;
+        }
+    }
+
+    close(in_sock);
+    ;
     close(out_sock);
-    if (rc == -1) 
-      eprintf("Error opening file: %s\n", KEY_FILE);
-    if (rc == 0) 
-      eprintf("No key found in %s\n", KEY_FILE);
-  }
-  len = pack_fingers_get(buf, client_addr, client_port, &key);
-
-  chordsrv.sin_family = h->h_addrtype;
-  chordsrv.sin_addr.s_addr = htonl(chordsrv_addr); 
-  chordsrv.sin_port = htons(chordsrv_port);
-
-  FD_ZERO(&fdset);
-  FD_SET(in_sock, &fdset);
-  nfds = in_sock + 1;
-
-  for (;;) {
-    /* send CHORD_FINGERS_GET request */
-    len = pack_client_traceroute(buf, ttl, &id, client_addr, client_port);
-    rc = sendto(out_sock, buf, len, 0, 
-               (struct sockaddr *)&chordsrv, sizeof(chordsrv));
-    if(rc < 0) {
-      printf("cannot send data, errno: %d \n", errno);
-      return -1;
-    }
-    
-    len = recv_packet(in_sock, fdset, nfds, (char*)buf, sizeof(buf),
-                     chordsrv_addr, chordsrv_port);
-    
-    if (len == -1 && retries < MAX_RETRIES) {
-      retries++;
-      continue;
-    }
-    if (len == -1 || 
-       (!unpack_client_traceroute_repl((char*)buf, len, ttl,
-                                       chordsrv_addr, chordsrv_port))) {
-      if (len == -1) {
-       printf("... giving up...\n");
-       printf("\nAlso, check whether file %s exists at the chord node,\n",
-              ACCLIST_FILE); 
-       printf("and if does, check whether it contains the key in %s\n",
-              KEY_FILE);
-       printf("(see README for details).\n");
-      }
-      break;
-    }
-    else {
-      retries = 0;
-      ttl++;
-    }
-  }
-
-  close(in_sock);;
-  close(out_sock);
-  printf("\n");
-
-  return 1;
+    printf("\n");
+
+    return 1;
 }
 
-
-/* this function unpacks the CHORD_FINGERS_REPL message 
+/* this function unpacks the CHORD_FINGERS_REPL message
  * and prints its content
  *
  * the function returns TRUE if the successor of the Chord node
@@ -196,137 +203,137 @@
  * number in succ_addr and succ_port variables
  */
 static int unpack_client_traceroute_repl(char *buf, int n, int orig_ttl,
-                                        ulong chordsrv_addr, 
-                                        ushort chordsrv_port)
+                                         ulong chordsrv_addr,
+                                         ushort chordsrv_port)
 {
-  chordID id;
-  char    type;
-  ulong   addr;
-  ushort  port; 
-  ulong   rtt_avg, rtt_dev;
-  int     len;
-  uchar   ttl, hops;
-  struct  in_addr ia;
-
-  len = unpack((uchar*)buf, "cccx", &type, &ttl, &hops, &id);
-
-  assert(type == CHORD_TRACEROUTE_REPL);
-
-  if (orig_ttl == 1) {
+    chordID id;
+    char type;
+    ulong addr;
+    ushort port;
+    ulong rtt_avg, rtt_dev;
+    int len;
+    uchar ttl, hops;
+    struct  in_addr ia;
+
+    len = unpack((uchar *) buf, "cccx", &type, &ttl, &hops, &id);
+
+    assert(type == CHORD_TRACEROUTE_REPL);
+
+    if (orig_ttl == 1) {
+        /* print the last link of the traceroute path */
+        len      += unpack((uchar *) (buf + len), "xls", &id, &addr, &port);
+
+        printf("First hop: (");
+        print_chordID(&id);
+        ia.s_addr = htonl(addr);
+        printf("), (%s:%d))\n", inet_ntoa(ia), port);
+        return TRUE;
+    }
+
+    if (ttl) {
+        /* the last hop has been already returned in the previous call */
+        return FALSE;
+    }
+
     /* print the last link of the traceroute path */
-    len += unpack((uchar *)(buf + len), "xls", &id, &addr, &port);
-    
-    printf("First hop: (");
+    len      += unpack((uchar *) (buf + len), "xlsll", &id, &addr, &port, 
&rtt_avg, &rtt_dev);
+
+    printf("\n(");
+    print_chordID(&id);
+    ia.s_addr = htonl(addr);
+    printf("), (%s:%d)) --> \n", inet_ntoa(ia), port);
+
+    len      += unpack((uchar *) (buf + len), "xls", &id, &addr, &port);
+    printf("   (");
     print_chordID(&id);
     ia.s_addr = htonl(addr);
     printf("), (%s:%d))\n", inet_ntoa(ia), port);
+
+    printf("        rtt_avg = %5.2f ms, rtt_stdev = %5.2f ms\n",
+           (float) rtt_avg / 1000., (float) rtt_dev / 1000.);
     return TRUE;
-  } 
-
-  if (ttl)
-    /* the last hop has been already returned in the previous call */ 
-    return FALSE;
-
-  /* print the last link of the traceroute path */
-  len += unpack((uchar*)(buf + len), "xlsll", &id, &addr, &port, &rtt_avg, 
&rtt_dev);
-  
-  printf("\n(");
-  print_chordID(&id);
-  ia.s_addr = htonl(addr);
-  printf("), (%s:%d)) --> \n", inet_ntoa(ia), port);
-  
-  len += unpack((uchar*)(buf + len), "xls", &id, &addr, &port);
-  printf("   (");
-  print_chordID(&id);
-  ia.s_addr = htonl(addr);
-  printf("), (%s:%d))\n", inet_ntoa(ia), port);
-  
-  printf("        rtt_avg = %5.2f ms, rtt_stdev = %5.2f ms\n",
-        (float)rtt_avg/1000., (float)rtt_dev/1000.);
-  return TRUE;
 }
 
-static int recv_packet(int in_sock, fd_set fdset, int nfds, 
-                      char *buf, int buf_len,
-                      ulong chordsrv_addr, ulong chordsrv_port)
+static int recv_packet(int in_sock, fd_set fdset, int nfds,
+                       char *buf, int buf_len,
+                       ulong chordsrv_addr, ulong chordsrv_port)
 {
-  fd_set readset;
-  int    nfound, from_len, len;
-  struct timeval timeout;
-  struct sockaddr_in from;
-
-  for (;;) {
-    readset = fdset;
-    /* set a timeout in case we cannot contact the Chord node */
-    timeout.tv_sec = SELECT_TIMEOUT;
-    timeout.tv_usec = 0;
-    nfound = select(nfds, &readset, NULL, NULL, &timeout);
-
-    if (nfound < 0 && errno == EINTR) {
-      continue;
-    }
-    if (nfound == 0) {
-      /* timeout expired */
-      struct  in_addr ia;
-      ia.s_addr = htonl(chordsrv_addr);
-      printf("\nCouldn't contact node (%s:%d), try again...\n", 
-            inet_ntoa(ia), (int)chordsrv_port);
-      return -1;
-    }
-    if (FD_ISSET(in_sock, &readset)) {
-      /* this is the reply from the Chord node */
-      from_len = sizeof(from);
-      len = recvfrom(in_sock, buf, buf_len, 0,
-                      (struct sockaddr *)&from, (uint*)&from_len);
-      if (len < 0) {
-       if (errno != EAGAIN) {
-         printf("recvfrom failed; ");  
-         continue;
-       }
-       weprintf("try again...");
-       continue;   
-      }
-      return len;
-    }
-  }
+    fd_set readset;
+    int nfound, from_len, len;
+    struct timeval timeout;
+    struct sockaddr_in from;
+
+    for (;; ) {
+        readset         = fdset;
+        /* set a timeout in case we cannot contact the Chord node */
+        timeout.tv_sec  = SELECT_TIMEOUT;
+        timeout.tv_usec = 0;
+        nfound          = select(nfds, &readset, NULL, NULL, &timeout);
+
+        if (nfound < 0 && errno == EINTR) {
+            continue;
+        }
+        if (nfound == 0) {
+            /* timeout expired */
+            struct  in_addr ia;
+            ia.s_addr = htonl(chordsrv_addr);
+            printf("\nCouldn't contact node (%s:%d), try again...\n",
+                   inet_ntoa(ia), (int) chordsrv_port);
+            return -1;
+        }
+        if (FD_ISSET(in_sock, &readset)) {
+            /* this is the reply from the Chord node */
+            from_len = sizeof(from);
+            len      = recvfrom(in_sock, buf, buf_len, 0,
+                                (struct sockaddr *) &from, (uint *) &from_len);
+            if (len < 0) {
+                if (errno != EAGAIN) {
+                    printf("recvfrom failed; ");
+                    continue;
+                }
+                weprintf("try again...");
+                continue;
+            }
+            return len;
+        }
+    }
 }
 
-
 /**********************************************************************/
 
 /* pack_client_traceroute: pack traceroute packet */
-/* 
+/*
  * traceroute packet format:
- *    char pkt_type; 
- *    char ttl; time to live, decremented at every hop. 
+ *    char pkt_type;
+ *    char ttl; time to live, decremented at every hop.
  *              When ttl reaches 0, a traceroute_repl packet is returned.
  *    char hops; number of hops up to the current node (not including the
- *               client). hops is inceremented at every hop along the 
- *               forward path. hops should be initialized to 0 by the clients. 
+ *               client). hops is inceremented at every hop along the
+ *               forward path. hops should be initialized to 0 by the clients.
  *    ID target_id;   target ID for traceroute.
- *    Node prev_node; previous node (ie., the node which forwarded the packet) 
+ *    Node prev_node; previous node (ie., the node which forwarded the packet)
  *    ulong rtt; rtt...
- *    ulong dev; ... and std dev frm previous node to this node (in usec)  
+ *    ulong dev; ... and std dev frm previous node to this node (in usec)
  *    Node crt_node; this node
- *    (list of addresses/ports of the nodes along the traceroute path 
+ *    (list of addresses/ports of the nodes along the traceroute path
  *     up to this node)
- *    ulong addr;  address...   
+ *    ulong addr;  address...
  *    ushort port; ... and port number of the client
  *    ....
  */
-static int pack_client_traceroute(uchar *buf, uchar ttl, chordID *id, 
-                                 ulong client_addr, ushort client_port)
+static int pack_client_traceroute(uchar *buf, uchar ttl, chordID *id,
+                                  ulong client_addr, ushort client_port)
 {
-  int   n = 0;
-
-  /* pack type, ttl, hops, and target id fields */
-  n = pack(buf+n, "cccx", CHORD_TRACEROUTE, ttl, 0, id);
-
-  /* skip prev node and next node fields */
-  n += sizeof_fmt("xlsllxls");
-
-  /* add client's address to the list of addresses .. */
-  n += pack(buf+n, "ls", client_addr, client_port);
-  
-  return n;
+    int n = 0;
+
+    /* pack type, ttl, hops, and target id fields */
+    n  = pack(buf + n, "cccx", CHORD_TRACEROUTE, ttl, 0, id);
+
+    /* skip prev node and next node fields */
+    n += sizeof_fmt("xlsllxls");
+
+    /* add client's address to the list of addresses .. */
+    n += pack(buf + n, "ls", client_addr, client_port);
+
+    return n;
 }

=== modified file 'i3/chord/debug.h'
--- i3/chord/debug.h    2009-12-11 22:49:11 +0000
+++ i3/chord/debug.h    2010-02-11 11:49:47 +0000
@@ -1,16 +1,16 @@
-/***************************************************************************
-                           debug.h  -  description
-                             -------------------
-    begin                : Mon Oct 2 2003
-    copyright            : (C) 2003 by ion
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef CHORD_DEBUG_H
-#define CHORD_DEBUG_H
-
-#define CHORD_DEBUG_LEVEL  3
-
-#define CHORD_DEBUG(level, x)  if (level <= CHORD_DEBUG_LEVEL) x;
-
-#endif
+/***************************************************************************
+*                          debug.h  -  description
+*                            -------------------
+*   begin                : Mon Oct 2 2003
+*   copyright            : (C) 2003 by ion
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef CHORD_DEBUG_H
+#define CHORD_DEBUG_H
+
+#define CHORD_DEBUG_LEVEL  3
+
+#define CHORD_DEBUG(level, x)  if (level <= CHORD_DEBUG_LEVEL) {x; }
+
+#endif

=== modified file 'i3/chord/eprintf.c'
--- i3/chord/eprintf.c  2009-12-11 22:49:11 +0000
+++ i3/chord/eprintf.c  2010-02-11 11:49:47 +0000
@@ -1,108 +1,117 @@
-/* Copyright (C) 1999 Lucent Technologies */
-/* Excerpted from 'The Practice of Programming' */
-/* by Brian W. Kernighan and Rob Pike */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include "eprintf.h"
-
-/* eprintf: print error message and exit */
-void eprintf(char *fmt, ...)
-{
-       va_list args;
-
-       fflush(stdout);
-       if (getprogname() != NULL)
-               fprintf(stderr, "%s: ", getprogname());
-
-       va_start(args, fmt);
-       vfprintf(stderr, fmt, args);
-       va_end(args);
-
-       if (fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':')
-               fprintf(stderr, " %s", strerror(errno));
-       fprintf(stderr, "\n");
-       exit(2); /* conventional value for failed execution */
-}
-
-/* weprintf: print warning message */
-void weprintf(char *fmt, ...)
-{
-       va_list args;
-
-       fflush(stdout);
-       fprintf(stderr, "warning: ");
-       if (getprogname() != NULL)
-               fprintf(stderr, "%s: ", getprogname());
-       va_start(args, fmt);
-       vfprintf(stderr, fmt, args);
-       va_end(args);
-       if (fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':')
-               fprintf(stderr, " %s\n", strerror(errno));
-       else
-               fprintf(stderr, "\n");
-}
-
-/* emalloc: malloc and report if error */
-void *emalloc(size_t n)
-{
-       void *p;
-
-       p = malloc(n);
-       if (p == NULL)
-               eprintf("malloc of %u bytes failed:", n);
-       return p;
-}
-
-/* erealloc: realloc and report if error */
-void *erealloc(void *vp, size_t n)
-{
-       void *p;
-
-       p = realloc(vp, n);
-       if (p == NULL)
-               eprintf("realloc of %u bytes failed:", n);
-       return p;
-}
-
-/* ecalloc: calloc and report if error */
-void *ecalloc(size_t n, size_t w)
-{
-        void *p;
-       
-       p = calloc(n, w);
-       if (p == NULL)
-               eprintf("calloc of %u x %u bytes failed:", n, w);
-       return p;
-}
-
-/* estrdup: duplicate a string, report if error */
-char *estrdup(char *s)
-{
-       char *t;
-
-       t = (char *) malloc(strlen(s)+1);
-       if (t == NULL)
-               eprintf("estrdup(\"%.20s\") failed:", s);
-       strcpy(t, s);
-       return t;
-}
-
-#ifndef __APPLE__
-static const char *progname;
-
-/* setprogname: set name of program */
-void setprogname(const char *name)
-{
-    progname = name;
-}
-
-/* getprogname: return name of program */
-const char *getprogname(void)
-{
-    return progname;
-}
-#endif
+/* Copyright (C) 1999 Lucent Technologies */
+/* Excerpted from 'The Practice of Programming' */
+/* by Brian W. Kernighan and Rob Pike */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include "eprintf.h"
+
+/* eprintf: print error message and exit */
+void eprintf(char *fmt, ...)
+{
+    va_list args;
+
+    fflush(stdout);
+    if (getprogname() != NULL) {
+        fprintf(stderr, "%s: ", getprogname());
+    }
+
+    va_start(args, fmt);
+    vfprintf(stderr, fmt, args);
+    va_end(args);
+
+    if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':') {
+        fprintf(stderr, " %s", strerror(errno));
+    }
+    fprintf(stderr, "\n");
+    exit(2);     /* conventional value for failed execution */
+}
+
+/* weprintf: print warning message */
+void weprintf(char *fmt, ...)
+{
+    va_list args;
+
+    fflush(stdout);
+    fprintf(stderr, "warning: ");
+    if (getprogname() != NULL) {
+        fprintf(stderr, "%s: ", getprogname());
+    }
+    va_start(args, fmt);
+    vfprintf(stderr, fmt, args);
+    va_end(args);
+    if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':') {
+        fprintf(stderr, " %s\n", strerror(errno));
+    } else {
+        fprintf(stderr, "\n");
+    }
+}
+
+/* emalloc: malloc and report if error */
+void *emalloc(size_t n)
+{
+    void *p;
+
+    p = malloc(n);
+    if (p == NULL) {
+        eprintf("malloc of %u bytes failed:", n);
+    }
+    return p;
+}
+
+/* erealloc: realloc and report if error */
+void *erealloc(void *vp, size_t n)
+{
+    void *p;
+
+    p = realloc(vp, n);
+    if (p == NULL) {
+        eprintf("realloc of %u bytes failed:", n);
+    }
+    return p;
+}
+
+/* ecalloc: calloc and report if error */
+void *ecalloc(size_t n, size_t w)
+{
+    void *p;
+
+    p = calloc(n, w);
+    if (p == NULL) {
+        eprintf("calloc of %u x %u bytes failed:", n, w);
+    }
+    return p;
+}
+
+/* estrdup: duplicate a string, report if error */
+char *estrdup(char *s)
+{
+    char *t;
+
+    t = (char *) malloc(strlen(s) + 1);
+    if (t == NULL) {
+        eprintf("estrdup(\"%.20s\") failed:", s);
+    }
+    strcpy(t, s);
+    return t;
+}
+
+#ifndef __APPLE__
+static const char *progname;
+
+/* setprogname: set name of program */
+void setprogname(const char *name)
+{
+    progname = name;
+}
+
+/* getprogname: return name of program */
+const char *getprogname(void)
+{
+    return progname;
+}
+
+#endif

=== modified file 'i3/chord/eprintf.h'
--- i3/chord/eprintf.h  2009-12-11 22:49:11 +0000
+++ i3/chord/eprintf.h  2010-02-11 11:49:47 +0000
@@ -1,17 +1,17 @@
-/* Copyright (C) 1999 Lucent Technologies */
-/* Excerpted from 'The Practice of Programming' */
-/* by Brian W. Kernighan and Rob Pike */
-
-/* eprintf.h: error wrapper functions */
-extern void    eprintf(char *, ...);
-extern void    weprintf(char *, ...);
-#ifdef CCURED
-#pragma ccuredvararg("eprintf", printf(1))
-#pragma ccuredvararg("weprintf", printf(1))
-#endif
-extern char    *estrdup(char *);
-extern void    *emalloc(size_t);
-extern void    *erealloc(void *, size_t);
-extern  void    *ecalloc(size_t, size_t);
-extern void    setprogname(const char *);
-extern const char*     getprogname(void);
+/* Copyright (C) 1999 Lucent Technologies */
+/* Excerpted from 'The Practice of Programming' */
+/* by Brian W. Kernighan and Rob Pike */
+
+/* eprintf.h: error wrapper functions */
+extern void    eprintf(char *, ...);
+extern void    weprintf(char *, ...);
+#ifdef CCURED
+#pragma ccuredvararg("eprintf", printf(1))
+#pragma ccuredvararg("weprintf", printf(1))
+#endif
+extern char    *estrdup(char *);
+extern void *emalloc(size_t);
+extern void *erealloc(void *, size_t);
+extern void *ecalloc(size_t, size_t);
+extern void    setprogname(const char *);
+extern const char *getprogname(void);

=== modified file 'i3/chord/finger.c'
--- i3/chord/finger.c   2009-12-11 22:49:11 +0000
+++ i3/chord/finger.c   2010-02-11 11:49:47 +0000
@@ -1,202 +1,211 @@
-#include <stdlib.h>
-#include <assert.h>
-#include "chord.h"
-
-/* new_finger: allocate and initialize finger structure */
-Finger *new_finger(Node *node)
-{
-    Finger *fp;
-
-    /* allocate space for new finger */
-    fp = emalloc(sizeof(Finger));
-    fp->node = *node;
-    fp->status = F_PASSIVE;
-    fp->npings = 0;
-    fp->next = fp->prev = NULL;
-    fp->rtt_avg = fp->rtt_dev = 0;
-    return fp;
-}
-
-/**********************************************************************/
-
-Finger *succ_finger(Server *srv)
-{
-  Finger *f;
-
-  for (f = srv->head_flist; f; f = f->next) {
-    if (f->status == F_ACTIVE) 
-      return f;
-  }
-  return NULL;
-}
-
-/**********************************************************************/
-
-Finger *pred_finger(Server *srv)
-{
-  Finger *f;
-
-  for (f = srv->tail_flist; f; f = f->prev) {
-    if (f->status == F_ACTIVE) 
-      return f;
-  }
-
-  return NULL;
-}
-
-/**********************************************************************/
-
-/* closest_preceding_node: search table for highest predecessor of id */
-/* closest_preceding_finger: search table for highest predecessor of id */
-
-Finger *closest_preceding_finger(Server *srv, chordID *id, int fall)
-{
-  Finger *f;
-
-  for (f = srv->tail_flist; f; f = f->prev) {
-    /* look only for active fingers; we do not know if we can
-     * reach the passive fingers
-     */
-    if ((fall == TRUE) || (f->status == F_ACTIVE)) {
-      if (is_between(&f->node.id, &srv->node.id, id))
-       return f;
-    }
-  }
-
-  return NULL;
-}
-
-Node *closest_preceding_node(Server *srv, chordID *id, int fall)
-{
-  Finger *f = closest_preceding_finger(srv, id, fall);
-
-  if (f == NULL)
-    return &(srv->node);
-  else
-    return &(f->node);
-}
-
-/**********************************************************************/
-
-Finger *get_finger(Server *srv, chordID *id)
-{
-  Finger *f;
-
-  for (f = srv->head_flist; f; f = f->next)
-    if (equals(id, &f->node.id))
-      return f;
-  return NULL;
-}
-
-/**********************************************************************/
-
-Finger *insert_finger(Server *srv, chordID *id, 
-                     in_addr_t addr, in_port_t port, int *fnew)
-{
-  Finger *f, *new_f, *pred;
-  Node   n;
-
-  assert((srv->node.addr != addr) || (srv->node.port != port));
-  pred = PRED(srv);
- 
-  f = get_finger(srv, id);
-
-  if (f) {
-    if (f->node.addr != addr) {
-      f->node.addr = addr;
-      f->node.port = port;
-      f->rtt_avg = f->rtt_dev = 0;
-      f->npings = 0;
-    }
-    /* f is already in the list. In this case, 
-     * f is not refreshed, i.e., f->npings is not set to 0.
-     * Refreshing f here might preclude the ping procedeure from removing
-     * f when it dies.
-     */
-    CHORD_DEBUG(5, print_server(srv, "[insert_finger(1)]", "end"));
-    *fnew = FALSE;
-    return f;
-  } 
-
-  n.id = *id; n.addr = addr; n.port = port;
-  new_f = new_finger(&n);
-
-  f = srv->head_flist;
-  if (f == NULL) {
-    /* this is the first finger */
-    srv->head_flist = srv->tail_flist = new_f;
-  } else {
-
-    f = closest_preceding_finger(srv, id, TRUE);
-    if (f == NULL) {
-      new_f->next = srv->head_flist;
-      new_f->prev = NULL;
-      srv->head_flist->prev = new_f;
-      srv->head_flist = new_f;
-    } else {    
-      new_f->next = f->next;
-      if (f->next)
-       f->next->prev = new_f;
-      else
-       srv->tail_flist = new_f;
-      new_f->prev = f;
-      f->next = new_f;
-    }
-  }
-
-  CHORD_DEBUG(5, print_server(srv, "[insert_finger(2)]", ""));
-
-  *fnew = TRUE;
-  return new_f;
-}
-  
-
-/**********************************************************************/
-
-void remove_finger(Server *srv, Finger *f)
-{
-  Finger *pred, *pf;
-  
-  pred = pred_finger(srv); /* remeber to check whether pred changes */
-
-  if ((srv->tail_flist != f) && (srv->head_flist != f)) {
-    f->prev->next = f->next;
-    f->next->prev = f->prev;
-  } else {
-    if (srv->head_flist == f) {
-      srv->head_flist = f->next;
-      if (f->next) f->next->prev = NULL;
-    } 
-    if (srv->tail_flist == f) {
-      srv->tail_flist = f->prev;
-      if (f->prev) f->prev->next = NULL;
-    } 
-  }
-
-  pf = pred_finger(srv);
-  if (pred != pf) {
-    if (pf == NULL) 
-      chord_update_range(&srv->node.id, &srv->node.id);
-    else
-      chord_update_range(&pf->node.id, &srv->node.id);
-  }
-
-  CHORD_DEBUG(5, print_server(srv, "[remove_finger]", ""));
-  free(f);
-}
-
-/**********************************************************************/
-
-void free_finger_list(Finger *flist)
-{
-  Finger *f;
-
-  while (flist) {
-    f = flist;
-    flist = flist->next;
-    free(f);
-  }
-}
-
-
-
+#include <stdlib.h>
+#include <assert.h>
+#include "chord.h"
+
+/* new_finger: allocate and initialize finger structure */
+Finger *new_finger(Node *node)
+{
+    Finger *fp;
+
+    /* allocate space for new finger */
+    fp          = emalloc(sizeof(Finger));
+    fp->node    = *node;
+    fp->status  = F_PASSIVE;
+    fp->npings  = 0;
+    fp->next    = fp->prev = NULL;
+    fp->rtt_avg = fp->rtt_dev = 0;
+    return fp;
+}
+
+/**********************************************************************/
+
+Finger *succ_finger(Server *srv)
+{
+    Finger *f;
+
+    for (f = srv->head_flist; f; f = f->next) {
+        if (f->status == F_ACTIVE) {
+            return f;
+        }
+    }
+    return NULL;
+}
+
+/**********************************************************************/
+
+Finger *pred_finger(Server *srv)
+{
+    Finger *f;
+
+    for (f = srv->tail_flist; f; f = f->prev) {
+        if (f->status == F_ACTIVE) {
+            return f;
+        }
+    }
+
+    return NULL;
+}
+
+/**********************************************************************/
+
+/* closest_preceding_node: search table for highest predecessor of id */
+/* closest_preceding_finger: search table for highest predecessor of id */
+
+Finger *closest_preceding_finger(Server *srv, chordID *id, int fall)
+{
+    Finger *f;
+
+    for (f = srv->tail_flist; f; f = f->prev) {
+        /* look only for active fingers; we do not know if we can
+         * reach the passive fingers
+         */
+        if ((fall == TRUE) || (f->status == F_ACTIVE)) {
+            if (is_between(&f->node.id, &srv->node.id, id)) {
+                return f;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+Node *closest_preceding_node(Server *srv, chordID *id, int fall)
+{
+    Finger *f = closest_preceding_finger(srv, id, fall);
+
+    if (f == NULL) {
+        return &(srv->node);
+    } else {
+        return &(f->node);
+    }
+}
+
+/**********************************************************************/
+
+Finger *get_finger(Server *srv, chordID *id)
+{
+    Finger *f;
+
+    for (f = srv->head_flist; f; f = f->next) {
+        if (equals(id, &f->node.id)) {
+            return f;
+        }
+    }
+    return NULL;
+}
+
+/**********************************************************************/
+
+Finger *insert_finger(Server *srv, chordID *id,
+                      in_addr_t addr, in_port_t port, int *fnew)
+{
+    Finger *f, *new_f, *pred;
+    Node n;
+
+    assert((srv->node.addr != addr) || (srv->node.port != port));
+    pred = PRED(srv);
+
+    f    = get_finger(srv, id);
+
+    if (f) {
+        if (f->node.addr != addr) {
+            f->node.addr = addr;
+            f->node.port = port;
+            f->rtt_avg   = f->rtt_dev = 0;
+            f->npings    = 0;
+        }
+        /* f is already in the list. In this case,
+         * f is not refreshed, i.e., f->npings is not set to 0.
+         * Refreshing f here might preclude the ping procedeure from removing
+         * f when it dies.
+         */
+        CHORD_DEBUG(5, print_server(srv, "[insert_finger(1)]", "end"));
+        *fnew = FALSE;
+        return f;
+    }
+
+    n.id   = *id;
+    n.addr = addr;
+    n.port = port;
+    new_f  = new_finger(&n);
+
+    f      = srv->head_flist;
+    if (f == NULL) {
+        /* this is the first finger */
+        srv->head_flist = srv->tail_flist = new_f;
+    } else {
+        f = closest_preceding_finger(srv, id, TRUE);
+        if (f == NULL) {
+            new_f->next           = srv->head_flist;
+            new_f->prev           = NULL;
+            srv->head_flist->prev = new_f;
+            srv->head_flist       = new_f;
+        } else {
+            new_f->next = f->next;
+            if (f->next) {
+                f->next->prev = new_f;
+            } else {
+                srv->tail_flist = new_f;
+            }
+            new_f->prev = f;
+            f->next     = new_f;
+        }
+    }
+
+    CHORD_DEBUG(5, print_server(srv, "[insert_finger(2)]", ""));
+
+    *fnew = TRUE;
+    return new_f;
+}
+
+/**********************************************************************/
+
+void remove_finger(Server *srv, Finger *f)
+{
+    Finger *pred, *pf;
+
+    pred = pred_finger(srv); /* remeber to check whether pred changes */
+
+    if ((srv->tail_flist != f) && (srv->head_flist != f)) {
+        f->prev->next = f->next;
+        f->next->prev = f->prev;
+    } else {
+        if (srv->head_flist == f) {
+            srv->head_flist = f->next;
+            if (f->next) {
+                f->next->prev = NULL;
+            }
+        }
+        if (srv->tail_flist == f) {
+            srv->tail_flist = f->prev;
+            if (f->prev) {
+                f->prev->next = NULL;
+            }
+        }
+    }
+
+    pf = pred_finger(srv);
+    if (pred != pf) {
+        if (pf == NULL) {
+            chord_update_range(&srv->node.id, &srv->node.id);
+        } else {
+            chord_update_range(&pf->node.id, &srv->node.id);
+        }
+    }
+
+    CHORD_DEBUG(5, print_server(srv, "[remove_finger]", ""));
+    free(f);
+}
+
+/**********************************************************************/
+
+void free_finger_list(Finger *flist)
+{
+    Finger *f;
+
+    while (flist) {
+        f     = flist;
+        flist = flist->next;
+        free(f);
+    }
+}

=== modified file 'i3/chord/gen_conf.c'
--- i3/chord/gen_conf.c 2009-12-29 15:10:11 +0000
+++ i3/chord/gen_conf.c 2010-02-11 11:49:47 +0000
@@ -1,201 +1,205 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <time.h>
-#include <unistd.h>
-#ifdef __APPLE__
-#include <sys/socket.h>
-#endif
-#include <net/if.h>
-#include <netdb.h>
-#include <sys/utsname.h>
-#include <sys/sysctl.h>
-#include <sys/ioctl.h>
-#include <string.h>
-
-#include "chord.h"
-
-#define IFNAME_LEN 256
-#define MAX_NUM_IFS 16
-
-#define NEWS
-
-/* get_addr: get IP address of server */
-ulong get_addr1(char *name, int* ok_flag)
-{
-    int i, tempfd, ret;
-    struct sockaddr_in tmp_addr;
-    char ifname[IFNAME_LEN];
-    struct ifreq ifr;
-
-    struct hostent *hptr;
-    struct utsname myname;
-
-    *ok_flag = 1;
-    
-    if (name == NULL) {
-      if (uname(&myname) < 0) {
-        printf("uname failed:");
-        *ok_flag = 0;
-        return 0;
-      }
-      name = myname.nodename;
-    }
-
-    hptr = gethostbyname(name);
-    if (!hptr) {
-        printf("gethostbyname(%s) failed", name);
-        *ok_flag =0;
-        return 0;
-    }
-    for (i = 0; i < hptr->h_length/sizeof(ulong); i++) {
-       struct in_addr ia;
-       ulong *addrptr;
-
-       addrptr = (ulong *) hptr->h_addr_list[i];
-       
-       ia.s_addr = *addrptr;
-       //printf("Addr %d = %s; ", i, inet_ntoa(ia));
-    }
-    
-    if (*((ulong *) hptr->h_addr) != inet_addr("127.0.0.1"))
-        return *((ulong *) hptr->h_addr);
-
-    // if not, ioctl on ethernet interface.
-    for (i = 0; i < MAX_NUM_IFS; i++) {
-        sprintf(ifname, "eth%d", i);
-        strcpy(ifr.ifr_name, ifname);
-        
-        tempfd = socket(AF_INET, SOCK_DGRAM, 0);
-
-        if (((ret = ioctl(tempfd, SIOCGIFFLAGS, (char *)&ifr)) != -1)) {
-            if ((ifr.ifr_flags & IFF_UP) != 0) {
-                if ((ret = ioctl(tempfd, SIOCGIFADDR, (char *)&ifr)) != -1) {
-                    tmp_addr = *((struct sockaddr_in *) &ifr.ifr_addr);
-                    return tmp_addr.sin_addr.s_addr;
-                }
-            }
-        }
-    }
-    
-    return inet_addr("127.0.0.1");
-}
-
-
-void set_loworder_bits(chordID *id)
-{
-    int i;
-#define ID_SERVER_LEN 6
-    for (i = ID_SERVER_LEN; i < ID_LEN; i++)
-       id->x[i] = 0xff;
-}
-
-int main(int argc, char **argv)
-{
-
-  /** Port offset is used when you want to start multiple sets of i3 servers
-    * on the same set of planetlab nodes.  The port numbers of the different
-    * i3 servers running on the same planetlab node should not clash.
-    * So we specificy an offset.
-    */
-  int port_offset = 0;
-  
-  int get_addr_ok_flag = 0;
-  
-  int i, j, k, i3_port, validate_port;
-  Node *nodes;
-  char filename[100], name[100];
-  FILE *fp, *fd, *i3clientconf_fd;
-#ifdef NEWS
-  FILE *newsconf_fd; 
-#endif
-  struct in_addr ia;
-#define MAX_NUM_NODES 1000
-
-  if (argc < 3) {
-    fprintf(stderr, "usage: %s server_list cfg_file_prefix [port_offset]\n", 
argv[0]);
-    exit(-1);
-  }
-
-  if (argc > 3) {
-     //Read the optional port offset which has been specified.
-        port_offset = atoi(argv[3]);
-  } else {
-        port_offset = 0;
-  }
-  
-  srandom(getpid() ^ time(0));
-
-  nodes = (Node *) malloc(MAX_NUM_NODES * sizeof(Node));
-
-  fd = fopen(argv[1], "r");
-  k = 0;
-  while (!feof(fd)) {
-    if (k == MAX_NUM_NODES)
-      break;
-
-    if( fscanf(fd, "%s\n", name) == EOF ){
-               perror("scanf error");
-       };
-    nodes[k].id = rand_ID();
-    //set_loworder_bits(&(nodes[k].id));
-    nodes[k].addr = ntohl(get_addr1(name, &get_addr_ok_flag));
-    nodes[k].port = (4710 + port_offset) + k;
-    if (get_addr_ok_flag) {
-        //advance counter only if we were able to successfully lookup the 
address
-        //This is equivalent to ignoring this node.
-        k++;
-    }
-  }
-  fclose(fd);
-
-  //create a directory to hold the configuration files
-  mkdir (argv[2], S_IRUSR|S_IWUSR|S_IEXEC);
-
-  sprintf(filename, "%s/%s_i3client.conf", argv[2], argv[2]);
-  i3clientconf_fd = fopen(filename, "w");
-#ifdef NEWS
-  sprintf(filename, "%s/%s_i3news.conf", argv[2], argv[2]);
-  newsconf_fd = fopen(filename, "w");
-#endif
-  
-  for (i = 0; i < k; i++) {
-    i3_port = nodes[i].port - (4710 + port_offset) + (5610 + port_offset);
-    validate_port = nodes[i].port - (4710 + port_offset) + (7810 + 
port_offset);
-    ia.s_addr = htonl(nodes[i].addr);
-    fprintf(i3clientconf_fd, "%s %d\n", inet_ntoa(ia), i3_port);
-#ifdef NEWS
-    fprintf(newsconf_fd, "%s %d %d ", inet_ntoa(ia), i3_port, validate_port);
-    print_id(newsconf_fd, &nodes[i].id);
-    fprintf(newsconf_fd, "\n");
-#endif
-
-#ifdef NEWS
-    sprintf(filename, "%s/%s_%s_%d_%d_%d.cfg",
-               argv[2], argv[2], inet_ntoa(ia), i3_port, validate_port, 
nodes[i].port);
-#else
-    sprintf(filename, "%s/%s_%s_%d_%d.cfg",
-           argv[2], argv[2], inet_ntoa(ia), i3_port, nodes[i].port);
-#endif
-    fp = fopen(filename, "w");
-    fprintf(fp, "%d ", nodes[i].port);
-    print_id(fp, &nodes[i].id);
-    fprintf(fp, "\n");
-    for (j = 0; j < k; j++) {
-      if (j == i) continue;
-      ia.s_addr = htonl(nodes[j].addr);
-      fprintf(fp, "%s:%d ", inet_ntoa(ia), nodes[j].port);
-      fprintf(fp, "\n");
-    }
-    fclose(fp);
-  }
-
-  fclose(i3clientconf_fd);
-#ifdef NEWS
-  fclose(newsconf_fd);
-#endif
-  return 0;
-}
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <unistd.h>
+#ifdef __APPLE__
+#include <sys/socket.h>
+#endif
+#include <net/if.h>
+#include <netdb.h>
+#include <sys/utsname.h>
+#include <sys/sysctl.h>
+#include <sys/ioctl.h>
+#include <string.h>
+
+#include "chord.h"
+
+#define IFNAME_LEN 256
+#define MAX_NUM_IFS 16
+
+#define NEWS
+
+/* get_addr: get IP address of server */
+ulong get_addr1(char *name, int *ok_flag)
+{
+    int i, tempfd, ret;
+    struct sockaddr_in tmp_addr;
+    char ifname[IFNAME_LEN];
+    struct ifreq ifr;
+
+    struct hostent *hptr;
+    struct utsname myname;
+
+    *ok_flag = 1;
+
+    if (name == NULL) {
+        if (uname(&myname) < 0) {
+            printf("uname failed:");
+            *ok_flag = 0;
+            return 0;
+        }
+        name = myname.nodename;
+    }
+
+    hptr = gethostbyname(name);
+    if (!hptr) {
+        printf("gethostbyname(%s) failed", name);
+        *ok_flag = 0;
+        return 0;
+    }
+    for (i = 0; i < hptr->h_length / sizeof(ulong); i++) {
+        struct in_addr ia;
+        ulong *addrptr;
+
+        addrptr   = (ulong *) hptr->h_addr_list[i];
+
+        ia.s_addr = *addrptr;
+        //printf("Addr %d = %s; ", i, inet_ntoa(ia));
+    }
+
+    if (*((ulong *) hptr->h_addr) != inet_addr("127.0.0.1")) {
+        return *((ulong *) hptr->h_addr);
+    }
+
+    // if not, ioctl on ethernet interface.
+    for (i = 0; i < MAX_NUM_IFS; i++) {
+        sprintf(ifname, "eth%d", i);
+        strcpy(ifr.ifr_name, ifname);
+
+        tempfd = socket(AF_INET, SOCK_DGRAM, 0);
+
+        if (((ret = ioctl(tempfd, SIOCGIFFLAGS, (char *) &ifr)) != -1)) {
+            if ((ifr.ifr_flags & IFF_UP) != 0) {
+                if ((ret = ioctl(tempfd, SIOCGIFADDR, (char *) &ifr)) != -1) {
+                    tmp_addr = *((struct sockaddr_in *) &ifr.ifr_addr);
+                    return tmp_addr.sin_addr.s_addr;
+                }
+            }
+        }
+    }
+
+    return inet_addr("127.0.0.1");
+}
+
+void set_loworder_bits(chordID *id)
+{
+    int i;
+#define ID_SERVER_LEN 6
+    for (i = ID_SERVER_LEN; i < ID_LEN; i++) {
+        id->x[i] = 0xff;
+    }
+}
+
+int main(int argc, char **argv)
+{
+    /** Port offset is used when you want to start multiple sets of i3 servers
+     * on the same set of planetlab nodes.  The port numbers of the different
+     * i3 servers running on the same planetlab node should not clash.
+     * So we specificy an offset.
+     */
+    int port_offset      = 0;
+
+    int get_addr_ok_flag = 0;
+
+    int i, j, k, i3_port, validate_port;
+    Node *nodes;
+    char filename[100], name[100];
+    FILE *fp, *fd, *i3clientconf_fd;
+#ifdef NEWS
+    FILE *newsconf_fd;
+#endif
+    struct in_addr ia;
+#define MAX_NUM_NODES 1000
+
+    if (argc < 3) {
+        fprintf(stderr, "usage: %s server_list cfg_file_prefix 
[port_offset]\n", argv[0]);
+        exit(-1);
+    }
+
+    if (argc > 3) {
+        //Read the optional port offset which has been specified.
+        port_offset = atoi(argv[3]);
+    } else {
+        port_offset = 0;
+    }
+
+    srandom(getpid() ^ time(0));
+
+    nodes = (Node *) malloc(MAX_NUM_NODES * sizeof(Node));
+
+    fd    = fopen(argv[1], "r");
+    k     = 0;
+    while (!feof(fd)) {
+        if (k == MAX_NUM_NODES) {
+            break;
+        }
+
+        if (fscanf(fd, "%s\n", name) == EOF) {
+            perror("scanf error");
+        }
+        ;
+        nodes[k].id   = rand_ID();
+        //set_loworder_bits(&(nodes[k].id));
+        nodes[k].addr = ntohl(get_addr1(name, &get_addr_ok_flag));
+        nodes[k].port = (4710 + port_offset) + k;
+        if (get_addr_ok_flag) {
+            //advance counter only if we were able to successfully lookup the 
address
+            //This is equivalent to ignoring this node.
+            k++;
+        }
+    }
+    fclose(fd);
+
+    //create a directory to hold the configuration files
+    mkdir(argv[2], S_IRUSR | S_IWUSR | S_IEXEC);
+
+    sprintf(filename, "%s/%s_i3client.conf", argv[2], argv[2]);
+    i3clientconf_fd = fopen(filename, "w");
+#ifdef NEWS
+    sprintf(filename, "%s/%s_i3news.conf", argv[2], argv[2]);
+    newsconf_fd     = fopen(filename, "w");
+#endif
+
+    for (i = 0; i < k; i++) {
+        i3_port       = nodes[i].port - (4710 + port_offset) + (5610 + 
port_offset);
+        validate_port = nodes[i].port - (4710 + port_offset) + (7810 + 
port_offset);
+        ia.s_addr     = htonl(nodes[i].addr);
+        fprintf(i3clientconf_fd, "%s %d\n", inet_ntoa(ia), i3_port);
+#ifdef NEWS
+        fprintf(newsconf_fd, "%s %d %d ", inet_ntoa(ia), i3_port, 
validate_port);
+        print_id(newsconf_fd, &nodes[i].id);
+        fprintf(newsconf_fd, "\n");
+#endif
+
+#ifdef NEWS
+        sprintf(filename, "%s/%s_%s_%d_%d_%d.cfg",
+                argv[2], argv[2], inet_ntoa(ia), i3_port, validate_port, 
nodes[i].port);
+#else
+        sprintf(filename, "%s/%s_%s_%d_%d.cfg",
+                argv[2], argv[2], inet_ntoa(ia), i3_port, nodes[i].port);
+#endif
+        fp = fopen(filename, "w");
+        fprintf(fp, "%d ", nodes[i].port);
+        print_id(fp, &nodes[i].id);
+        fprintf(fp, "\n");
+        for (j = 0; j < k; j++) {
+            if (j == i) {
+                continue;
+            }
+            ia.s_addr = htonl(nodes[j].addr);
+            fprintf(fp, "%s:%d ", inet_ntoa(ia), nodes[j].port);
+            fprintf(fp, "\n");
+        }
+        fclose(fp);
+    }
+
+    fclose(i3clientconf_fd);
+#ifdef NEWS
+    fclose(newsconf_fd);
+#endif
+    return 0;
+}

=== modified file 'i3/chord/gen_conf_same.c'
--- i3/chord/gen_conf_same.c    2009-12-11 22:49:11 +0000
+++ i3/chord/gen_conf_same.c    2010-02-11 11:49:47 +0000
@@ -1,49 +1,51 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <time.h>
-#include <unistd.h>
-#include "chord.h"
-
-int main(int argc, char **argv)
-{
-  int i, j, n;
-  Node *nodes;
-  in_addr_t addr;
-  char filename[100];
-  FILE *fp;
-  struct in_addr ia;
-
-  if (argc != 2) {
-    fprintf(stderr, "ussage: %s num_servers\n", argv[0]);
-    exit(-1);
-  }
-  n = atoi(argv[1]);
-  srandom(getpid() ^ time(0));
-
-  addr = ntohl(get_addr());
-
-  nodes = (Node *) malloc(n * sizeof(Node));
-  for (i = 0; i < n; i++) {
-    nodes[i].id = rand_ID();
-    nodes[i].addr = addr;
-    nodes[i].port = 6500 + i;
-  }
-
-  for (i = 0; i < n; i++) {
-    sprintf(filename, "conf.%d", i);
-    fp = fopen(filename, "w");
-    fprintf(fp, "%d ", nodes[i].port);
-    print_id(fp, &nodes[i].id);
-    fprintf(fp, "\n");
-    for (j = 0; j < n; j++) {
-      if (j == i) continue;
-      ia.s_addr = htonl(nodes[j].addr);
-      fprintf(fp, "%s:%d\n", inet_ntoa(ia), nodes[j].port);
-    }
-    fclose(fp);
-  }
-
-  return 0;
-}
+#include <stdlib.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <time.h>
+#include <unistd.h>
+#include "chord.h"
+
+int main(int argc, char **argv)
+{
+    int i, j, n;
+    Node *nodes;
+    in_addr_t addr;
+    char filename[100];
+    FILE *fp;
+    struct in_addr ia;
+
+    if (argc != 2) {
+        fprintf(stderr, "ussage: %s num_servers\n", argv[0]);
+        exit(-1);
+    }
+    n     = atoi(argv[1]);
+    srandom(getpid() ^ time(0));
+
+    addr  = ntohl(get_addr());
+
+    nodes = (Node *) malloc(n * sizeof(Node));
+    for (i = 0; i < n; i++) {
+        nodes[i].id   = rand_ID();
+        nodes[i].addr = addr;
+        nodes[i].port = 6500 + i;
+    }
+
+    for (i = 0; i < n; i++) {
+        sprintf(filename, "conf.%d", i);
+        fp = fopen(filename, "w");
+        fprintf(fp, "%d ", nodes[i].port);
+        print_id(fp, &nodes[i].id);
+        fprintf(fp, "\n");
+        for (j = 0; j < n; j++) {
+            if (j == i) {
+                continue;
+            }
+            ia.s_addr = htonl(nodes[j].addr);
+            fprintf(fp, "%s:%d\n", inet_ntoa(ia), nodes[j].port);
+        }
+        fclose(fp);
+    }
+
+    return 0;
+}

=== modified file 'i3/chord/hosts.c'
--- i3/chord/hosts.c    2010-01-06 22:17:32 +0000
+++ i3/chord/hosts.c    2010-02-11 11:49:47 +0000
@@ -1,135 +1,136 @@
-/* host registration (mainly for testing) */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/utsname.h>
-#include <sys/ioctl.h>
-#include <sys/sysctl.h>
-#include <netdb.h>
-#include <net/if.h>
-#include "chord.h"
-
-#define TRIVIAL_LOCAL_ADDR     "127.0.0.1"
-#define MAX_NUM_INTERFACES     3
-#define IFNAME_LEN             256
-
-/***************************************************************************
- * 
- * Purpose: Get IP address of local machine by ioctl on eth0-ethk
- * 
- * Return: As an unsigned long in network byte order
- *
- **************************************************************************/
-static uint32_t get_local_addr_eth(void)
-{
-  int i, tempfd;
-  struct sockaddr_in addr;
-  char ifname[IFNAME_LEN];
-  struct ifreq ifr;            
-  
-  for (i = 0; i < MAX_NUM_INTERFACES; i++) {
-    sprintf(ifname, "eth%d", i);
-    strcpy(ifr.ifr_name, ifname);
-    tempfd = socket(AF_INET, SOCK_DGRAM, 0);
-    
-    if (-1 != ioctl(tempfd, SIOCGIFFLAGS, (char *)&ifr)) {
-      if (0 != (ifr.ifr_flags & IFF_UP)) {
-       if (-1 != ioctl(tempfd, SIOCGIFADDR, (char *)&ifr)) {
-         addr = *((struct sockaddr_in *) &ifr.ifr_addr);
-         close(tempfd);
-         return addr.sin_addr.s_addr;
-       }
-      }
-    }
-    close(tempfd);
-  }
-  
-  return inet_addr(TRIVIAL_LOCAL_ADDR);
-}
-
-/***************************************************************************
- * 
- * Purpose: Get the IP address of an arbitrary machine
- *     given the name of the machine
- * 
- * Return: As an unsigned long in network byte order
- *
- **************************************************************************/
-static uint32_t name_to_addr(const char *name)
-{
-    int i;
-    struct hostent *hptr = gethostbyname(name);
-    if (!hptr) {
-      weprintf("gethostbyname(%s) failed", name);
-    }
-    else {
-      for (i = 0; i < hptr->h_length/sizeof(uint32_t); i++) {
-       uint32_t addr = *((uint32_t *) hptr->h_addr_list[i]);
-       if (inet_addr(TRIVIAL_LOCAL_ADDR) != addr)
-         return addr;
-      }
-    }
-    return 0;
-}
-
-
-/***************************************************************************
- * 
- * Purpose: Get IP address of local machine by uname/gethostbyname
- * 
- * Return: As an unsigned long in network byte order
- *
- **************************************************************************/
-static uint32_t get_local_addr_uname(void)
-{
-  struct utsname myname;
-  uint32_t addr = 0;
-
-  if (uname(&myname) < 0) {
-    weprintf("uname failed:");
-  } else {
-    addr = name_to_addr(myname.nodename);
-  }
-  
-  if (addr == 0)
-    return inet_addr(TRIVIAL_LOCAL_ADDR);
-  else
-    return addr;
-}
-
-/***************************************************************************
- * 
- * Purpose: Get IP address of local machine
- * 
- * Return: As an unsigned long in network byte order
- *
- **************************************************************************/
-static uint32_t get_local_addr(void)
-{
-  uint32_t addr;
-  
-  /* First try uname/gethostbyname */
-  if ((addr = get_local_addr_uname()) != inet_addr(TRIVIAL_LOCAL_ADDR))
-    return addr;
-  /* If that is unsuccessful, try ioctl on eth interfaces */
-  if ((addr = get_local_addr_eth()) != inet_addr(TRIVIAL_LOCAL_ADDR))
-    return addr;
-  
-  /* This is hopeless, return TRIVIAL_IP */
-  return(inet_addr(TRIVIAL_LOCAL_ADDR));
-}
-
-/***********************************************************************/
-/* get_addr: get IP address of server */
-in_addr_t
-get_addr(void)
-{
-  return (in_addr_t) get_local_addr();
-}
+/* host registration (mainly for testing) */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/utsname.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <netdb.h>
+#include <net/if.h>
+#include "chord.h"
+
+#define TRIVIAL_LOCAL_ADDR      "127.0.0.1"
+#define MAX_NUM_INTERFACES      3
+#define IFNAME_LEN              256
+
+/***************************************************************************
+ *
+ * Purpose: Get IP address of local machine by ioctl on eth0-ethk
+ *
+ * Return: As an unsigned long in network byte order
+ *
+ **************************************************************************/
+static uint32_t get_local_addr_eth(void)
+{
+    int i, tempfd;
+    struct sockaddr_in addr;
+    char ifname[IFNAME_LEN];
+    struct ifreq ifr;
+
+    for (i = 0; i < MAX_NUM_INTERFACES; i++) {
+        sprintf(ifname, "eth%d", i);
+        strcpy(ifr.ifr_name, ifname);
+        tempfd = socket(AF_INET, SOCK_DGRAM, 0);
+
+        if (-1 != ioctl(tempfd, SIOCGIFFLAGS, (char *) &ifr)) {
+            if (0 != (ifr.ifr_flags & IFF_UP)) {
+                if (-1 != ioctl(tempfd, SIOCGIFADDR, (char *) &ifr)) {
+                    addr = *((struct sockaddr_in *) &ifr.ifr_addr);
+                    close(tempfd);
+                    return addr.sin_addr.s_addr;
+                }
+            }
+        }
+        close(tempfd);
+    }
+
+    return inet_addr(TRIVIAL_LOCAL_ADDR);
+}
+
+/***************************************************************************
+ *
+ * Purpose: Get the IP address of an arbitrary machine
+ *    given the name of the machine
+ *
+ * Return: As an unsigned long in network byte order
+ *
+ **************************************************************************/
+static uint32_t name_to_addr(const char *name)
+{
+    int i;
+    struct hostent *hptr = gethostbyname(name);
+    if (!hptr) {
+        weprintf("gethostbyname(%s) failed", name);
+    } else {
+        for (i = 0; i < hptr->h_length / sizeof(uint32_t); i++) {
+            uint32_t addr = *((uint32_t *) hptr->h_addr_list[i]);
+            if (inet_addr(TRIVIAL_LOCAL_ADDR) != addr) {
+                return addr;
+            }
+        }
+    }
+    return 0;
+}
+
+/***************************************************************************
+ *
+ * Purpose: Get IP address of local machine by uname/gethostbyname
+ *
+ * Return: As an unsigned long in network byte order
+ *
+ **************************************************************************/
+static uint32_t get_local_addr_uname(void)
+{
+    struct utsname myname;
+    uint32_t addr = 0;
+
+    if (uname(&myname) < 0) {
+        weprintf("uname failed:");
+    } else {
+        addr = name_to_addr(myname.nodename);
+    }
+
+    if (addr == 0) {
+        return inet_addr(TRIVIAL_LOCAL_ADDR);
+    } else {
+        return addr;
+    }
+}
+
+/***************************************************************************
+ *
+ * Purpose: Get IP address of local machine
+ *
+ * Return: As an unsigned long in network byte order
+ *
+ **************************************************************************/
+static uint32_t get_local_addr(void)
+{
+    uint32_t addr;
+
+    /* First try uname/gethostbyname */
+    if ((addr = get_local_addr_uname()) != inet_addr(TRIVIAL_LOCAL_ADDR)) {
+        return addr;
+    }
+    /* If that is unsuccessful, try ioctl on eth interfaces */
+    if ((addr = get_local_addr_eth()) != inet_addr(TRIVIAL_LOCAL_ADDR)) {
+        return addr;
+    }
+
+    /* This is hopeless, return TRIVIAL_IP */
+    return inet_addr(TRIVIAL_LOCAL_ADDR);
+}
+
+/***********************************************************************/
+/* get_addr: get IP address of server */
+in_addr_t get_addr(void)
+{
+    return (in_addr_t) get_local_addr();
+}

=== modified file 'i3/chord/join.c'
--- i3/chord/join.c     2009-12-11 22:49:11 +0000
+++ i3/chord/join.c     2010-02-11 11:49:47 +0000
@@ -1,42 +1,44 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/utsname.h>
-#include "chord.h"
-
-/* join: Send join messages to hosts in file */
-void join(Server *srv, FILE *fp)
-{
-    char addr[100], *p;
-    struct hostent *hp;
-
-    // printf("join\n");
-    while (nknown < MAX_WELLKNOWN && fscanf(fp, " %s\n", addr) == 1) {
-        p = strchr(addr, ':');
-       printf("addr=%s\n", addr);
-        assert(p != NULL);
-       *(p++) = '\0';
-
-       /* resolve address */   
-       hp = gethostbyname(addr);
-       if (hp == NULL)
-           eprintf("gethostbyname(%s) failed:", addr);
-
-       well_known[nknown].addr = ntohl(*((in_addr_t *) hp->h_addr));
-       well_known[nknown].port = (in_port_t) atoi(p);
-       nknown++;
-    }
-
-    if (nknown == 0)
-        printf("Didn't find any known hosts.");
-       // eprintf("Didn't find any known hosts."); xxxx
-
-    chord_update_range(&srv->node.id, &srv->node.id);
-    set_stabilize_timer();
-    stabilize(srv);
-}
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/utsname.h>
+#include "chord.h"
+
+/* join: Send join messages to hosts in file */
+void join(Server *srv, FILE *fp)
+{
+    char addr[100], *p;
+    struct hostent *hp;
+
+    // printf("join\n");
+    while (nknown < MAX_WELLKNOWN && fscanf(fp, " %s\n", addr) == 1) {
+        p                       = strchr(addr, ':');
+        printf("addr=%s\n", addr);
+        assert(p != NULL);
+        *(p++)                  = '\0';
+
+        /* resolve address */
+        hp                      = gethostbyname(addr);
+        if (hp == NULL) {
+            eprintf("gethostbyname(%s) failed:", addr);
+        }
+
+        well_known[nknown].addr = ntohl(*((in_addr_t *) hp->h_addr));
+        well_known[nknown].port = (in_port_t) atoi(p);
+        nknown++;
+    }
+
+    if (nknown == 0) {
+        printf("Didn't find any known hosts.");
+    }
+    // eprintf("Didn't find any known hosts."); xxxx
+
+    chord_update_range(&srv->node.id, &srv->node.id);
+    set_stabilize_timer();
+    stabilize(srv);
+}

=== modified file 'i3/chord/pack.c'
--- i3/chord/pack.c     2009-12-11 22:49:11 +0000
+++ i3/chord/pack.c     2010-02-11 11:49:47 +0000
@@ -1,584 +1,593 @@
-#include <stdarg.h>
-#include <string.h>
-#include <assert.h>
-#include "chord.h"
-
-/* pack: pack binary items into buf, return length */
-
-int pack(uchar *buf, char *fmt, ...)
-{
-  va_list args;
-  char *p;
-  uchar *bp;
-  chordID *id;
-  ushort s;
-  ulong l;
-
-  bp = buf;
-  va_start(args, fmt);
-  for (p = fmt; *p != '\0'; p++) {
-    switch (*p) {
-    case 'c':   /* char */
-      *bp++ = va_arg(args, int);
-      break;
-    case 's':   /* short */
-      s = va_arg(args, int);
-      s = htons(s);
-      memmove(bp, (char *)&s, sizeof(ushort));
-      bp += sizeof(ushort);
-      break;
-    case 'l':   /* long */
-      l = va_arg(args, ulong);
-      l = htonl(l);
-      memmove(bp, (char *)&l, sizeof(ulong));
-      bp += sizeof(ulong);
-      break;
-    case 'x':   /* id */
-      id = va_arg(args, chordID *);
-      memmove(bp, id->x, ID_LEN);
-      bp += ID_LEN;
-      break;
-    default:   /* illegal type character */
-      va_end(args);
-      return -1;
-    }
-  }
-  va_end(args);
-  return bp - buf;
-}
-
-/**********************************************************************/
-
-/* unpack: unpack binary items from buf, return length */
-int unpack(uchar *buf, char *fmt, ...)
-{
-  va_list args;
-  char *p;
-  uchar *bp, *pc;
-  chordID *id;
-  ushort *ps;
-  ulong *pl;
-  
-  bp = buf;  
-  va_start(args, fmt);
-  for (p = fmt; *p != '\0'; p++) {
-    switch (*p) {
-    case 'c':   /* char */
-      pc = va_arg(args, uchar*);
-      *pc = *bp++;
-      break;
-    case 's':   /* short */
-      ps = va_arg(args, ushort*);
-      *ps = ntohs(*(ushort*)bp);
-      bp += sizeof(ushort);
-      break;
-    case 'l':   /* long */
-      pl = va_arg(args, ulong*);
-      *pl  = ntohl(*(ulong*)bp);
-      bp += sizeof(ulong);
-      break;
-    case 'x':   /* id */
-      id = va_arg(args, chordID *);
-      memmove(id->x, bp, ID_LEN);
-      bp += ID_LEN;
-      break;
-    default:   /* illegal type character */
-      va_end(args);
-      return -1;
-    }
-  }
-  va_end(args);
-  return bp - buf;
-}
-
-/**********************************************************************/
-
-int sizeof_fmt(char *fmt)
-{
-  int len = 0;
-  int i;
-
-  for (i = 0; i < strlen(fmt); i++) {
-    switch (fmt[i]) {
-    case 'c':   /* char */
-      len += sizeof(char);
-      break;
-    case 's':   /* short */
-      len += sizeof(ushort);
-      break;
-    case 'l':   /* long */
-      len += sizeof(ulong);
-      break;
-    case 'x':   /* id */
-      len += ID_LEN;
-      break;
-    default:   /* illegal type character */
-      eprintf("fmt_len: illegal type character.\n");
-      return -1;
-    }
-  }
-  return len;
-}
-
-/**********************************************************************/
-
-static int (*unpackfn[])(Server *, int, uchar *) = {
-  unpack_data,
-  unpack_data,
-  unpack_fs,
-  unpack_fs_repl,
-  unpack_stab,
-  unpack_stab_repl,
-  unpack_notify,
-  unpack_ping,
-  unpack_pong,
-  unpack_fingers_get,
-  unpack_fingers_repl,
-  unpack_traceroute,
-  unpack_traceroute,
-  unpack_traceroute_repl,
-};
-
-/* dispatch: unpack and process packet */
-int dispatch(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  int res;
-
-  type = buf[0];
-  
-  if (type >= NELEMS(unpackfn)) {
-    printf("bad packet type 0x%x\n", type);
-    return -1;
-  }
-  res = (*unpackfn[type])(srv, n, buf);
-  if (res == -1) 
-      printf("protocol error, type %x length %d\n", type, n);
-  return res;
-}
-
-/**********************************************************************/
-
-/* pack_data: pack data packet */
-int pack_data(uchar *buf, uchar type, byte ttl, chordID *id, 
-             ushort len, uchar *data)
-{
-  int n;
-
-  n = pack(buf, "ccxs", type, ttl, id, len);
-  if (n >= 0) {
-    memmove(buf + n, data, len);
-    n += len;
-  }
-  return n;
-}
-
-/**********************************************************************/
-
-/* unpack_data: unpack and process data packet */
-int unpack_data(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  byte  ttl;
-  int len;
-  chordID id;
-  ushort pkt_len;
-
-  len = unpack(buf, "ccxs", &type, &ttl, id.x, &pkt_len);
-  if (len < 0 || len + pkt_len != n) 
-    return -1;
-  if (--ttl == 0) { 
-    print_two_chordIDs("TTL expired: data packet ", &id, 
-                      " dropped at node ", &srv->node.id, "\n");
-    return -2;
-  }
-  assert(type == CHORD_ROUTE || type == CHORD_ROUTE_LAST);
-  return process_data(srv, type, ttl, &id, pkt_len, buf + len);
-}
-
-/**********************************************************************/
-
-/* pack_fs: pack find_successor packet */
-int pack_fs(uchar *buf, byte ttl, chordID *id, ulong addr, ushort port)
-{
-  return pack(buf, "ccxls", CHORD_FS, ttl, id, addr, port);
-}
-
-/**********************************************************************/
-
-/* unpack_fs: unpack and process find_successor packet */
-int unpack_fs(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  byte  ttl;
-  ulong addr;
-  ushort port;
-  chordID id;
-
-  if (unpack(buf, "ccxls", &type, &ttl, &id, &addr, &port) != n)
-    return -1;
-  if (--ttl == 0) {
-    print_two_chordIDs("TTL expired: fix_finger packet ", &id, 
-                      " dropped at node ", &srv->node.id, "\n");
-    return -2;
-  }
-  assert(type == CHORD_FS);
-  return process_fs(srv, ttl, &id, addr, port);
-}
-
-/**********************************************************************/
-
-/* pack_fs_repl: pack find_successor reply packet */
-int pack_fs_repl(uchar *buf, chordID *id, ulong addr, ushort port)
-{
-  return pack(buf, "cxls", CHORD_FS_REPL, id, addr, port);
-}
-
-/**********************************************************************/
-
-/* unpack_fs_repl: unpack and process find_successor reply packet */
-int unpack_fs_repl(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  ulong addr;
-  ushort port;
-  chordID id;
-
-  if (unpack(buf, "cxls", &type, &id, &addr, &port) != n)
-    return -1;
-  assert(type == CHORD_FS_REPL);
-  return process_fs_repl(srv, &id, addr, port);
-}
-
-/**********************************************************************/
-
-/* pack_stab: pack stabilize packet */
-int pack_stab(uchar *buf, chordID *id, ulong addr, ushort port)
-{
-  return pack(buf, "cxls", CHORD_STAB, id, addr, port);
-}
-
-/**********************************************************************/
-
-/* unpack_stab: unpack and process stabilize packet */
-int unpack_stab(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  ulong addr;
-  ushort port;
-  chordID id;
-
-  if (unpack(buf, "cxls", &type, &id, &addr, &port) != n)
-    return -1;
-  assert(type == CHORD_STAB);
-  return process_stab(srv, &id, addr, port);
-}
-
-/**********************************************************************/
-
-/* pack_stab_repl: pack stabilize reply packet */
-int pack_stab_repl(uchar *buf, chordID *id, ulong addr, ushort port)
-{
-  return pack(buf, "cxls", CHORD_STAB_REPL, id, addr, port);
-}
-
-/**********************************************************************/
-
-/* unpack_stab_repl: unpack and process stabilize reply packet */
-int unpack_stab_repl(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  ulong addr;
-  ushort port;
-  chordID id;
-
-  if (unpack(buf, "cxls", &type, &id, &addr, &port) != n)
-    return -1;
-  assert(type == CHORD_STAB_REPL);
-  return process_stab_repl(srv, &id, addr, port);
-}
-
-/**********************************************************************/
-
-/* pack_notify: pack notify packet */
-int pack_notify(uchar *buf, chordID *id, ulong addr, ushort port)
-{
-  return pack(buf, "cxls", CHORD_NOTIFY, id, addr, port);
-}
-
-/**********************************************************************/
-
-/* unpack_notify: unpack notify packet */
-int unpack_notify(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  ulong addr;
-  ushort port;
-  chordID id;
-
-  if (unpack(buf, "cxls", &type, &id, &addr, &port) != n)
-    return -1;
-  assert(type == CHORD_NOTIFY);
-  return process_notify(srv, &id, addr, port);
-}
-
-/**********************************************************************/
-
-/* pack_ping: pack ping packet */
-int pack_ping(uchar *buf, chordID *id, ulong addr, ushort port, ulong time)
-{
-  return pack(buf, "cxlsl", CHORD_PING, id, addr, port, time);
-}
-
-/**********************************************************************/
-
-/* unpack_ping: unpack and process ping packet */
-int unpack_ping(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  chordID id;
-  ulong addr;
-  ushort port;
-  ulong time;
-
-  if (unpack(buf, "cxlsl", &type, &id, &addr, &port, &time) != n)
-    return -1;
-  assert(type == CHORD_PING);
-  return process_ping(srv, &id, addr, port, time);
-}
-
-/**********************************************************************/
-
-/* pack_pong: pack pong packet */
-int pack_pong(uchar *buf, chordID *id, ulong addr, ushort port, ulong time)
-{
-  return pack(buf, "cxlsl", CHORD_PONG, id, addr, port, time);
-}
-
-/**********************************************************************/
-
-/* unpack_pong: unpack pong packet */
-int unpack_pong(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  ulong addr;
-  ushort port;
-  chordID id;
-  ulong   time;
-
-  if (unpack(buf, "cxlsl", &type, &id, &addr, &port, &time) != n)
-    return -1;
-  assert(type == CHORD_PONG);
-  return process_pong(srv, &id, addr, port, time);
-}
-
-/**********************************************************************/
-/**********************************************************************/
-
-/* pack_fingers_get: pack get fingers packet */
-int pack_fingers_get(uchar *buf, ulong addr, ushort port, Key *key)
-{
-  return pack(buf, "cxls", CHORD_FINGERS_GET, key, addr, port);
-}
-
-/**********************************************************************/
-
-/* unpack_fingers_get: unpack and process fingers_get packet */
-int unpack_fingers_get(Server *srv, int n, uchar *buf)
-{
-  uchar type;
-  Key   key;
-  ulong addr;
-  ushort port;
-
-  if (unpack(buf, "cxls", &type, &key, &addr, &port) != n)
-    return -1;
-  assert(type == CHORD_FINGERS_GET);
-  return process_fingers_get(srv, addr, port, &key);
-}
-
-#define INCOMPLETE_FINGER_LIST -1
-#define END_FINGER_LIST 0
-
-/* pack_fingers_repl: pack repl fingers packet */
-int pack_fingers_repl(uchar *buf, Server *srv)
-{
-  Finger *f;
-  int len, l;
-
-  assert(srv);
-  len = pack(buf, "cxls", CHORD_FINGERS_REPL, &srv->node.id, 
-            srv->node.addr, srv->node.port);
-
-  /* pack fingers */
-  for (f = srv->head_flist; f; f = f->next) {
-    l = pack(buf + len, "xlslls",
-             &f->node.id, f->node.addr, f->node.port,
-            f->rtt_avg, f->rtt_dev, (short)f->npings); 
-    len += l;
-    if (len + l + 1 > BUFSIZE) {
-      len += pack(buf + len, "c", INCOMPLETE_FINGER_LIST);
-      return len;
-    }
-  }
-  len += pack(buf + len, "c", END_FINGER_LIST);
-  return len;
-}
-
-
-/* unpack_fingers_repl: unpack and process fingers_repl packet */
-int unpack_fingers_repl(Server *srv, int n, uchar *buf)
-{
-  /* this message is received by a client; 
-   * it shouldn't be received by an i3 server 
-   */
-  return process_fingers_repl(srv, 0);
-}
-
-
-/**********************************************************************/
-
-/* pack_traceroute: pack/update traceroute packet */
-/* 
- * traceroute packet format:
- *    char pkt_type; 
- *    char ttl; time to live, decremented at every hop. 
- *              When ttl reaches 0, a traceroute_repl packet is returned.
- *    char hops; number of hops up to the current node (not including the
- *               client). hops is inceremented at every hop along the 
- *               forward path. hops should be initialized to 0 by the clients. 
- *    ID target_id;   target ID for traceroute.
- *    Node prev_node; previous node (ie., the node which forwarded the packet) 
- *    ulong rtt; rtt...
- *    ulong dev; ... and std dev frm previous node to this node (in usec)  
- *    Node crt_node; this node
- *    (list of addresses/ports of the nodes along the traceroute path 
- *     up to this node)
- *    ulong addr;  address...   
- *    ushort port; ... and port number of the client
- *    ....
- */
-int pack_traceroute(uchar *buf, Server *srv, Finger *f, 
-                   uchar type, byte ttl, byte hops)
-{
-  int   n = 0;
-
-  /* pack type, ttl and hops fields */
-  n = pack(buf+n, "ccc", type, ttl, hops);
-  
-  /* skip target ID field */
-  n += sizeof_fmt("x");
-
-  /* pack prev node (for the next node, this is the current node!) */
-  n += pack(buf+n, "xlsll", &srv->node.id, srv->node.addr, srv->node.port,
-           f->rtt_avg, f->rtt_dev);
-
-  /* pack this node field (for next node this is the node itself!) */
-  n += pack(buf+n, "xls", &f->node.id, f->node.addr, f->node.port);
-
-  /* skip current list of addresses .. */
-  n += sizeof_fmt("ls")*hops;
-
-  /* add current node to the list */
-  n += pack(buf+n, "ls", srv->node.addr, srv->node.port);
-
-  return n;
-}
-
-/**********************************************************************/
-
-/* unpack_traceroute: unpack and process trace_route packet 
- * (see pack_traceroute for packet format)
- */
-int unpack_traceroute(Server *srv, int n, uchar *buf)
-{
-  chordID id;
-  byte    type;
-  byte    ttl;
-  byte    hops;
-
-  /* unpack following fields: type, ttl, hops, and target id */
-  if (unpack(buf, "cccx", &type, &ttl, &hops, &id) >= n)
-    return -1;
-  assert(type == CHORD_TRACEROUTE || type == CHORD_TRACEROUTE_LAST);
-  return process_traceroute(srv, &id, (char *)buf, type, ttl, hops);
-}
-
-/**********************************************************************/
-
-/* pack_traceroute_repl: pack/update traceroute packet */
-/* 
- * traceroute packet_repl format:
- *    char pkt_type; 
- *    char ttl; time to live, incremented at every hop (remember, this message
- *              travls on the reverse path)
- *    char hops; number of hops from client, decremented at every
- *               hop along the forward path. When hops reaches 0,
- *               the packet is dropped.
- *    ID target_id;   target ID for traceroute.
- *    Node nl_node; next-to-last hop on traceroute path
- *    ulong rtt; rtt...
- *    ulong dev; ... and std dev from next-to-last hop to the last hop
- *    Node l_node; last node of traceroute path
- *    (list of addresses/ports of the nodes along the traceroute path 
- *     up to this node, starting with the client)
- *    ulong addr;  address...   
- *    ushort port; ... and port number of the client
- *    ....
- */
-int pack_traceroute_repl(uchar *buf, Server *srv, byte ttl, byte hops,
-                        ulong *paddr, ushort *pport, int one_hop)
-{
-  int   n = 0;
-
-  /* pack ttl and hops fields */
-  n += pack(buf+n, "ccc", CHORD_TRACEROUTE_REPL, (char)ttl, (char)hops);
-  
-  /* skip target ID field */
-  n += sizeof_fmt("x");
-
-  if (one_hop) {
-    /* one hop path */
-    n += pack(buf+n, "xls", &srv->node.id, srv->node.addr, srv->node.port);
-    /* skip mean rtt, and std dev rtt fields */
-    n += sizeof_fmt("ll");
-  } else {
-    /* skip next-to-last node field, and the mean and std dev. to last 
-     * node fields
-     */
-    n += sizeof_fmt("xlsll");
-  }
-
-  /* skip last node field */
-  n += sizeof_fmt("xls");
-
-  /* compute source list size -- this is the number of hops plus client */
-  n += sizeof_fmt("ls")*hops;
-
-  /* get address and port number of previous node on reverse path
-   * yes, it's ugly to unpack in a pack function, but... 
-   */
-  unpack(buf+n, "ls", paddr, pport);
-
-  return n;
-}
-
-/**********************************************************************/
-
-/*  unpack_traceroute: unpack and process trace_route packet 
- * (see pack_traceroute for packet format)
- */
-int unpack_traceroute_repl(Server *srv, int n, uchar *buf)
-{
-  byte type;
-  byte ttl;
-  byte hops;
-
-  /* unpack following fields: type, ttl, and hops */
-  if (unpack(buf, "ccc", &type, &ttl, &hops) >= n)
-    return -1;
-  assert(type == CHORD_TRACEROUTE_REPL);
-
-  return process_traceroute_repl(srv, (char *)buf, ttl, hops);
-}
-
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+#include "chord.h"
+
+/* pack: pack binary items into buf, return length */
+
+int pack(uchar *buf, char *fmt, ...)
+{
+    va_list args;
+    char *p;
+    uchar *bp;
+    chordID *id;
+    ushort s;
+    ulong l;
+
+    bp = buf;
+    va_start(args, fmt);
+    for (p = fmt; *p != '\0'; p++) {
+        switch (*p) {
+        case 'c': /* char */
+            *bp++ = va_arg(args, int);
+            break;
+        case 's': /* short */
+            s     = va_arg(args, int);
+            s     = htons(s);
+            memmove(bp, (char *) &s, sizeof(ushort));
+            bp   += sizeof(ushort);
+            break;
+        case 'l': /* long */
+            l     = va_arg(args, ulong);
+            l     = htonl(l);
+            memmove(bp, (char *) &l, sizeof(ulong));
+            bp   += sizeof(ulong);
+            break;
+        case 'x': /* id */
+            id    = va_arg(args, chordID *);
+            memmove(bp, id->x, ID_LEN);
+            bp   += ID_LEN;
+            break;
+        default: /* illegal type character */
+            va_end(args);
+            return -1;
+        }
+    }
+    va_end(args);
+    return bp - buf;
+}
+
+/**********************************************************************/
+
+/* unpack: unpack binary items from buf, return length */
+int unpack(uchar *buf, char *fmt, ...)
+{
+    va_list args;
+    char *p;
+    uchar *bp, *pc;
+    chordID *id;
+    ushort *ps;
+    ulong *pl;
+
+    bp = buf;
+    va_start(args, fmt);
+    for (p = fmt; *p != '\0'; p++) {
+        switch (*p) {
+        case 'c': /* char */
+            pc  = va_arg(args, uchar *);
+            *pc = *bp++;
+            break;
+        case 's': /* short */
+            ps  = va_arg(args, ushort *);
+            *ps = ntohs(*(ushort *) bp);
+            bp += sizeof(ushort);
+            break;
+        case 'l': /* long */
+            pl  = va_arg(args, ulong *);
+            *pl = ntohl(*(ulong *) bp);
+            bp += sizeof(ulong);
+            break;
+        case 'x': /* id */
+            id  = va_arg(args, chordID *);
+            memmove(id->x, bp, ID_LEN);
+            bp += ID_LEN;
+            break;
+        default: /* illegal type character */
+            va_end(args);
+            return -1;
+        }
+    }
+    va_end(args);
+    return bp - buf;
+}
+
+/**********************************************************************/
+
+int sizeof_fmt(char *fmt)
+{
+    int len = 0;
+    int i;
+
+    for (i = 0; i < strlen(fmt); i++) {
+        switch (fmt[i]) {
+        case 'c': /* char */
+            len += sizeof(char);
+            break;
+        case 's': /* short */
+            len += sizeof(ushort);
+            break;
+        case 'l': /* long */
+            len += sizeof(ulong);
+            break;
+        case 'x': /* id */
+            len += ID_LEN;
+            break;
+        default: /* illegal type character */
+            eprintf("fmt_len: illegal type character.\n");
+            return -1;
+        }
+    }
+    return len;
+}
+
+/**********************************************************************/
+
+static int (*unpackfn[])(Server *, int, uchar *) = {
+    unpack_data,
+    unpack_data,
+    unpack_fs,
+    unpack_fs_repl,
+    unpack_stab,
+    unpack_stab_repl,
+    unpack_notify,
+    unpack_ping,
+    unpack_pong,
+    unpack_fingers_get,
+    unpack_fingers_repl,
+    unpack_traceroute,
+    unpack_traceroute,
+    unpack_traceroute_repl,
+};
+
+/* dispatch: unpack and process packet */
+int dispatch(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    int res;
+
+    type = buf[0];
+
+    if (type >= NELEMS(unpackfn)) {
+        printf("bad packet type 0x%x\n", type);
+        return -1;
+    }
+    res = (*unpackfn[type])(srv, n, buf);
+    if (res == -1) {
+        printf("protocol error, type %x length %d\n", type, n);
+    }
+    return res;
+}
+
+/**********************************************************************/
+
+/* pack_data: pack data packet */
+int pack_data(uchar *buf, uchar type, byte ttl, chordID *id,
+              ushort len, uchar *data)
+{
+    int n;
+
+    n = pack(buf, "ccxs", type, ttl, id, len);
+    if (n >= 0) {
+        memmove(buf + n, data, len);
+        n += len;
+    }
+    return n;
+}
+
+/**********************************************************************/
+
+/* unpack_data: unpack and process data packet */
+int unpack_data(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    byte ttl;
+    int len;
+    chordID id;
+    ushort pkt_len;
+
+    len = unpack(buf, "ccxs", &type, &ttl, id.x, &pkt_len);
+    if (len < 0 || len + pkt_len != n) {
+        return -1;
+    }
+    if (--ttl == 0) {
+        print_two_chordIDs("TTL expired: data packet ", &id,
+                           " dropped at node ", &srv->node.id, "\n");
+        return -2;
+    }
+    assert(type == CHORD_ROUTE || type == CHORD_ROUTE_LAST);
+    return process_data(srv, type, ttl, &id, pkt_len, buf + len);
+}
+
+/**********************************************************************/
+
+/* pack_fs: pack find_successor packet */
+int pack_fs(uchar *buf, byte ttl, chordID *id, ulong addr, ushort port)
+{
+    return pack(buf, "ccxls", CHORD_FS, ttl, id, addr, port);
+}
+
+/**********************************************************************/
+
+/* unpack_fs: unpack and process find_successor packet */
+int unpack_fs(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    byte ttl;
+    ulong addr;
+    ushort port;
+    chordID id;
+
+    if (unpack(buf, "ccxls", &type, &ttl, &id, &addr, &port) != n) {
+        return -1;
+    }
+    if (--ttl == 0) {
+        print_two_chordIDs("TTL expired: fix_finger packet ", &id,
+                           " dropped at node ", &srv->node.id, "\n");
+        return -2;
+    }
+    assert(type == CHORD_FS);
+    return process_fs(srv, ttl, &id, addr, port);
+}
+
+/**********************************************************************/
+
+/* pack_fs_repl: pack find_successor reply packet */
+int pack_fs_repl(uchar *buf, chordID *id, ulong addr, ushort port)
+{
+    return pack(buf, "cxls", CHORD_FS_REPL, id, addr, port);
+}
+
+/**********************************************************************/
+
+/* unpack_fs_repl: unpack and process find_successor reply packet */
+int unpack_fs_repl(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    ulong addr;
+    ushort port;
+    chordID id;
+
+    if (unpack(buf, "cxls", &type, &id, &addr, &port) != n) {
+        return -1;
+    }
+    assert(type == CHORD_FS_REPL);
+    return process_fs_repl(srv, &id, addr, port);
+}
+
+/**********************************************************************/
+
+/* pack_stab: pack stabilize packet */
+int pack_stab(uchar *buf, chordID *id, ulong addr, ushort port)
+{
+    return pack(buf, "cxls", CHORD_STAB, id, addr, port);
+}
+
+/**********************************************************************/
+
+/* unpack_stab: unpack and process stabilize packet */
+int unpack_stab(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    ulong addr;
+    ushort port;
+    chordID id;
+
+    if (unpack(buf, "cxls", &type, &id, &addr, &port) != n) {
+        return -1;
+    }
+    assert(type == CHORD_STAB);
+    return process_stab(srv, &id, addr, port);
+}
+
+/**********************************************************************/
+
+/* pack_stab_repl: pack stabilize reply packet */
+int pack_stab_repl(uchar *buf, chordID *id, ulong addr, ushort port)
+{
+    return pack(buf, "cxls", CHORD_STAB_REPL, id, addr, port);
+}
+
+/**********************************************************************/
+
+/* unpack_stab_repl: unpack and process stabilize reply packet */
+int unpack_stab_repl(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    ulong addr;
+    ushort port;
+    chordID id;
+
+    if (unpack(buf, "cxls", &type, &id, &addr, &port) != n) {
+        return -1;
+    }
+    assert(type == CHORD_STAB_REPL);
+    return process_stab_repl(srv, &id, addr, port);
+}
+
+/**********************************************************************/
+
+/* pack_notify: pack notify packet */
+int pack_notify(uchar *buf, chordID *id, ulong addr, ushort port)
+{
+    return pack(buf, "cxls", CHORD_NOTIFY, id, addr, port);
+}
+
+/**********************************************************************/
+
+/* unpack_notify: unpack notify packet */
+int unpack_notify(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    ulong addr;
+    ushort port;
+    chordID id;
+
+    if (unpack(buf, "cxls", &type, &id, &addr, &port) != n) {
+        return -1;
+    }
+    assert(type == CHORD_NOTIFY);
+    return process_notify(srv, &id, addr, port);
+}
+
+/**********************************************************************/
+
+/* pack_ping: pack ping packet */
+int pack_ping(uchar *buf, chordID *id, ulong addr, ushort port, ulong time)
+{
+    return pack(buf, "cxlsl", CHORD_PING, id, addr, port, time);
+}
+
+/**********************************************************************/
+
+/* unpack_ping: unpack and process ping packet */
+int unpack_ping(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    chordID id;
+    ulong addr;
+    ushort port;
+    ulong time;
+
+    if (unpack(buf, "cxlsl", &type, &id, &addr, &port, &time) != n) {
+        return -1;
+    }
+    assert(type == CHORD_PING);
+    return process_ping(srv, &id, addr, port, time);
+}
+
+/**********************************************************************/
+
+/* pack_pong: pack pong packet */
+int pack_pong(uchar *buf, chordID *id, ulong addr, ushort port, ulong time)
+{
+    return pack(buf, "cxlsl", CHORD_PONG, id, addr, port, time);
+}
+
+/**********************************************************************/
+
+/* unpack_pong: unpack pong packet */
+int unpack_pong(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    ulong addr;
+    ushort port;
+    chordID id;
+    ulong time;
+
+    if (unpack(buf, "cxlsl", &type, &id, &addr, &port, &time) != n) {
+        return -1;
+    }
+    assert(type == CHORD_PONG);
+    return process_pong(srv, &id, addr, port, time);
+}
+
+/**********************************************************************/
+/**********************************************************************/
+
+/* pack_fingers_get: pack get fingers packet */
+int pack_fingers_get(uchar *buf, ulong addr, ushort port, Key *key)
+{
+    return pack(buf, "cxls", CHORD_FINGERS_GET, key, addr, port);
+}
+
+/**********************************************************************/
+
+/* unpack_fingers_get: unpack and process fingers_get packet */
+int unpack_fingers_get(Server *srv, int n, uchar *buf)
+{
+    uchar type;
+    Key key;
+    ulong addr;
+    ushort port;
+
+    if (unpack(buf, "cxls", &type, &key, &addr, &port) != n) {
+        return -1;
+    }
+    assert(type == CHORD_FINGERS_GET);
+    return process_fingers_get(srv, addr, port, &key);
+}
+
+#define INCOMPLETE_FINGER_LIST -1
+#define END_FINGER_LIST 0
+
+/* pack_fingers_repl: pack repl fingers packet */
+int pack_fingers_repl(uchar *buf, Server *srv)
+{
+    Finger *f;
+    int len, l;
+
+    assert(srv);
+    len = pack(buf, "cxls", CHORD_FINGERS_REPL, &srv->node.id,
+               srv->node.addr, srv->node.port);
+
+    /* pack fingers */
+    for (f = srv->head_flist; f; f = f->next) {
+        l    = pack(buf + len, "xlslls",
+                    &f->node.id, f->node.addr, f->node.port,
+                    f->rtt_avg, f->rtt_dev, (short) f->npings);
+        len += l;
+        if (len + l + 1 > BUFSIZE) {
+            len += pack(buf + len, "c", INCOMPLETE_FINGER_LIST);
+            return len;
+        }
+    }
+    len += pack(buf + len, "c", END_FINGER_LIST);
+    return len;
+}
+
+/* unpack_fingers_repl: unpack and process fingers_repl packet */
+int unpack_fingers_repl(Server *srv, int n, uchar *buf)
+{
+    /* this message is received by a client;
+     * it shouldn't be received by an i3 server
+     */
+    return process_fingers_repl(srv, 0);
+}
+
+/**********************************************************************/
+
+/* pack_traceroute: pack/update traceroute packet */
+/*
+ * traceroute packet format:
+ *    char pkt_type;
+ *    char ttl; time to live, decremented at every hop.
+ *              When ttl reaches 0, a traceroute_repl packet is returned.
+ *    char hops; number of hops up to the current node (not including the
+ *               client). hops is inceremented at every hop along the
+ *               forward path. hops should be initialized to 0 by the clients.
+ *    ID target_id;   target ID for traceroute.
+ *    Node prev_node; previous node (ie., the node which forwarded the packet)
+ *    ulong rtt; rtt...
+ *    ulong dev; ... and std dev frm previous node to this node (in usec)
+ *    Node crt_node; this node
+ *    (list of addresses/ports of the nodes along the traceroute path
+ *     up to this node)
+ *    ulong addr;  address...
+ *    ushort port; ... and port number of the client
+ *    ....
+ */
+int pack_traceroute(uchar *buf, Server *srv, Finger *f,
+                    uchar type, byte ttl, byte hops)
+{
+    int n = 0;
+
+    /* pack type, ttl and hops fields */
+    n  = pack(buf + n, "ccc", type, ttl, hops);
+
+    /* skip target ID field */
+    n += sizeof_fmt("x");
+
+    /* pack prev node (for the next node, this is the current node!) */
+    n += pack(buf + n, "xlsll", &srv->node.id, srv->node.addr, srv->node.port,
+              f->rtt_avg, f->rtt_dev);
+
+    /* pack this node field (for next node this is the node itself!) */
+    n += pack(buf + n, "xls", &f->node.id, f->node.addr, f->node.port);
+
+    /* skip current list of addresses .. */
+    n += sizeof_fmt("ls") * hops;
+
+    /* add current node to the list */
+    n += pack(buf + n, "ls", srv->node.addr, srv->node.port);
+
+    return n;
+}
+
+/**********************************************************************/
+
+/* unpack_traceroute: unpack and process trace_route packet
+ * (see pack_traceroute for packet format)
+ */
+int unpack_traceroute(Server *srv, int n, uchar *buf)
+{
+    chordID id;
+    byte type;
+    byte ttl;
+    byte hops;
+
+    /* unpack following fields: type, ttl, hops, and target id */
+    if (unpack(buf, "cccx", &type, &ttl, &hops, &id) >= n) {
+        return -1;
+    }
+    assert(type == CHORD_TRACEROUTE || type == CHORD_TRACEROUTE_LAST);
+    return process_traceroute(srv, &id, (char *) buf, type, ttl, hops);
+}
+
+/**********************************************************************/
+
+/* pack_traceroute_repl: pack/update traceroute packet */
+/*
+ * traceroute packet_repl format:
+ *    char pkt_type;
+ *    char ttl; time to live, incremented at every hop (remember, this message
+ *              travls on the reverse path)
+ *    char hops; number of hops from client, decremented at every
+ *               hop along the forward path. When hops reaches 0,
+ *               the packet is dropped.
+ *    ID target_id;   target ID for traceroute.
+ *    Node nl_node; next-to-last hop on traceroute path
+ *    ulong rtt; rtt...
+ *    ulong dev; ... and std dev from next-to-last hop to the last hop
+ *    Node l_node; last node of traceroute path
+ *    (list of addresses/ports of the nodes along the traceroute path
+ *     up to this node, starting with the client)
+ *    ulong addr;  address...
+ *    ushort port; ... and port number of the client
+ *    ....
+ */
+int pack_traceroute_repl(uchar *buf, Server *srv, byte ttl, byte hops,
+                         ulong *paddr, ushort *pport, int one_hop)
+{
+    int n = 0;
+
+    /* pack ttl and hops fields */
+    n += pack(buf + n, "ccc", CHORD_TRACEROUTE_REPL, (char) ttl, (char) hops);
+
+    /* skip target ID field */
+    n += sizeof_fmt("x");
+
+    if (one_hop) {
+        /* one hop path */
+        n += pack(buf + n, "xls", &srv->node.id, srv->node.addr, 
srv->node.port);
+        /* skip mean rtt, and std dev rtt fields */
+        n += sizeof_fmt("ll");
+    } else {
+        /* skip next-to-last node field, and the mean and std dev. to last
+         * node fields
+         */
+        n += sizeof_fmt("xlsll");
+    }
+
+    /* skip last node field */
+    n += sizeof_fmt("xls");
+
+    /* compute source list size -- this is the number of hops plus client */
+    n += sizeof_fmt("ls") * hops;
+
+    /* get address and port number of previous node on reverse path
+     * yes, it's ugly to unpack in a pack function, but...
+     */
+    unpack(buf + n, "ls", paddr, pport);
+
+    return n;
+}
+
+/**********************************************************************/
+
+/*  unpack_traceroute: unpack and process trace_route packet
+ * (see pack_traceroute for packet format)
+ */
+int unpack_traceroute_repl(Server *srv, int n, uchar *buf)
+{
+    byte type;
+    byte ttl;
+    byte hops;
+
+    /* unpack following fields: type, ttl, and hops */
+    if (unpack(buf, "ccc", &type, &ttl, &hops) >= n) {
+        return -1;
+    }
+    assert(type == CHORD_TRACEROUTE_REPL);
+
+    return process_traceroute_repl(srv, (char *) buf, ttl, hops);
+}

=== modified file 'i3/chord/process.c'
--- i3/chord/process.c  2009-12-11 22:49:11 +0000
+++ i3/chord/process.c  2010-02-11 11:49:47 +0000
@@ -1,284 +1,287 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include "chord.h"
-
-int process_data(Server *srv, uchar type, 
-                byte ttl, chordID *id, ushort len, uchar *data)
-{
-  Node   *np;
-  Finger *pf, *sf;
-
-  CHORD_DEBUG(5, print_process(srv, "process_data", id, -1, -1)); 
-  
-    /* handle request locally? */
-#ifdef SIM_CHORD
-    if (sim_chord_is_local(srv, id)) {
-       /* Upcall goes here... */
-        sim_deliver_data(srv, id, len, data);
-#else
-    if (chord_is_local(id)) {
-       /* Upcall goes here... */
-        chord_deliver(len, data);
-#endif
-       return 1;
-    } 
-    if ((type == CHORD_ROUTE_LAST) && ((pf = pred_finger(srv)) != NULL)) {
-      /* the previous hop N believes we are responsible for id,
-       * but we aren't. This means that our predecessor is
-       * a better successor for N. Just pass the packet to our
-       * predecessor. Note that ttl takes care of loops!
-       */
-      send_data(srv, CHORD_ROUTE_LAST, ttl, &pf->node, id, len, data);
-      return 1;
-    } 
-    if ((sf = succ_finger(srv)) != NULL) {
-      if (is_between(id, &srv->node.id, &sf->node.id) || 
-         equals(id, &sf->node.id)) {
-       /* according to our info the successor should be responsible
-         * for id; send the packet to the successor.
-        */
-       send_data(srv, CHORD_ROUTE_LAST, ttl, &sf->node, id, len, data);
-       return 1;
-      }
-    }
-    /* send packet to the closest active predecessor (that we know about) */
-    np = closest_preceding_node(srv, id, FALSE);
-    send_data(srv, CHORD_ROUTE, ttl, np, id, len, data);
-    return 1;
-}
-
-/**********************************************************************/
-
-int process_fs(Server *srv, byte ttl, chordID *id, ulong addr, ushort port)
-{
-  Node *succ, *np;
-
-  if (srv->node.addr == addr && srv->node.port == port)
-    return 1;
-
-  CHORD_DEBUG(5, print_process(srv, "process_fs", id, addr, port));
-
-  if (succ_finger(srv) == NULL) {
-    send_fs_repl(srv, addr, port, 
-                &srv->node.id, srv->node.addr, srv->node.port);
-    return 0;
-  }
-  succ = &(succ_finger(srv)->node);
-  if (is_between(id, &srv->node.id, &succ->id) || equals(id, &succ->id)) {
-    send_fs_repl(srv, addr, port, &succ->id, succ->addr, succ->port);
-  } else {
-    np = closest_preceding_node(srv, id, FALSE);
-    send_fs(srv, ttl, np->addr, np->port, id, addr, port);
-  }
-  return 1;
-}
-
-/**********************************************************************/
-
-int process_fs_repl(Server *srv, chordID *id, ulong addr, ushort port)
-{
-  int fnew;
-
-  if (srv->node.addr == addr && srv->node.port == port)
-    return 1;
-
-  CHORD_DEBUG(5, print_process(srv, "process_fs_repl", id, -1, -1));
-  insert_finger(srv, id, addr, port, &fnew);
-  if (fnew == TRUE) {
-    send_ping(srv, addr, port, 
-             srv->node.addr, srv->node.port, get_current_time());
-  }
-
-  return 1;
-}
-
-/**********************************************************************/
-
-int process_stab(Server *srv, chordID *id, ulong addr, ushort port)
-{
-  Finger *pred = pred_finger(srv);
-  int     fnew;
-
-  CHORD_DEBUG(5, print_process(srv, "process_stab", id, addr, port)); 
-
-  insert_finger(srv, id, addr, port, &fnew);
-  if (pred) {
-    send_stab_repl(srv, addr, port, 
-                  &pred->node.id, pred->node.addr, pred->node.port);
-  }
-  return 1;
-}
-
-/**********************************************************************/
-
-int process_stab_repl(Server *srv, chordID *id, ulong addr, ushort port)
-{
-  Finger *succ;
-  int     fnew;
-
-  CHORD_DEBUG(5, print_process(srv, "process_stab_repl", id, -1, -1)); 
-
-  if ((srv->node.addr == addr) && (srv->node.port == port))
-    return 1;
-  insert_finger(srv, id, addr, port, &fnew);
-  succ = succ_finger(srv);
-  send_notify(srv, succ->node.addr, succ->node.port,
-             &srv->node.id, srv->node.addr, srv->node.port);
-  if (fnew == TRUE) {
-    send_ping(srv, addr, port, 
-             srv->node.addr, srv->node.port, get_current_time());
-  }
-  return 1;
-}
-
-/**********************************************************************/
-
-int process_notify(Server *srv, chordID *id, ulong addr, ushort port)
-{
-  int fnew;
-
-  CHORD_DEBUG(5, print_process(srv, "process_notify", id, addr, port)); 
-  insert_finger(srv, id, addr, port, &fnew);
-  if (fnew == TRUE) {
-    send_ping(srv, addr, port, 
-             srv->node.addr, srv->node.port, get_current_time());
-  }
-  return 1;
-}
-
-/**********************************************************************/
-
-int process_ping(Server *srv, chordID *id, ulong addr, ushort port, ulong time)
-{
-  int fnew;
-  Finger *pred;
-
-  CHORD_DEBUG(5, print_process(srv, "process_ping", id, addr, port)); 
-  insert_finger(srv, id, addr, port, &fnew);
-  pred = pred_finger(srv);
-  if (fnew == TRUE && ((pred == NULL) || 
-                      (pred && is_between(id, &pred->node.id, 
-                                          &srv->node.id)))) {
-    send_ping(srv, addr, port, 
-             srv->node.addr, srv->node.port, get_current_time());
-  }
-
-  send_pong(srv, addr, port, time);
-  
-  return 1;
-}
-
-/**********************************************************************/
-
-int process_pong(Server *srv, chordID *id, ulong addr, ushort port, ulong time)
-{
-  Finger *f, *pred, *newpred;
-  ulong   new_rtt;
-  int     fnew;
-
-  CHORD_DEBUG(5, print_process(srv, "process_pong", id, addr, port)); 
-  f = insert_finger(srv, id, addr, port, &fnew);
-  f->npings = 0;
-  new_rtt = get_current_time() - time; /* takes care of overlow */
-  update_rtt(&f->rtt_avg, &f->rtt_dev, (long)new_rtt); 
-
-  pred = pred_finger(srv);
-  f->status = F_ACTIVE; /* there is a two-way connectivity to this node */
-  newpred = pred_finger(srv); /* check whether pred has changed, i.e.,
-                              * f has became the new pred
-                              */
-  assert(newpred || (pred == newpred));
-
-  if (pred != newpred)
-    chord_update_range(&newpred->node.id, &srv->node.id);
-
-  return 1;
-}
-
-/**********************************************************************/
-
-int process_fingers_get(Server *srv, ulong addr, ushort port, Key *key)
-{
-  CHORD_DEBUG(5, print_process(srv, "process_fingers_get", NULL, addr, port));
-  if (match_key(key) == 0) 
-    print_server(srv, "[process_fingers_get: invalid key]", "");
-  else 
-    send_fingers_repl(srv, addr, port);
-
-  return 1;
-}
-
-/**********************************************************************/
-
-int process_fingers_repl(Server *srv, uchar ret_code)
-{
-  /* this process should be never invoked by the i3 server,
-   * as CHORD_FINGERS_REPL is always sent to the client
-   */
-  CHORD_DEBUG(5, print_process(srv, "process_fingers_repl", NULL, 0, 0)); 
-  return 1;
-}
-
-/**********************************************************************/
-
-int process_traceroute(Server *srv, chordID *id, char *buf,
-                      uchar type, byte ttl, byte hops)
-{
-    Finger *f;
-
-    CHORD_DEBUG(5, print_process(srv, "process_traceroute", id, -1, -1)); 
-
-    assert(ttl);
-    ttl--;
-
-    /* handle request locally? */
-#ifdef SIM_CHORD
-    if (sim_chord_is_local(srv, id) || (ttl == 0)) {
-        send_traceroute_repl(srv, buf, ttl, hops, (hops ? FALSE : TRUE));
-#else
-    if (chord_is_local(id) || (ttl == 0)) {
-        send_traceroute_repl(srv, (uchar *)buf, ttl, hops, (hops ? FALSE : 
TRUE));
-#endif
-       return 1;
-    } 
-    hops++;
-    if ((type == CHORD_TRACEROUTE_LAST) && (f = pred_finger(srv))) {
-      /* the previous hop N believes we are responsible for id,
-       * but we aren't. This means that our predecessor is
-       * a better successor for N. Just pass the packet to our
-       * predecessor. Note that ttl takes care of loops.
-       */
-      send_traceroute(srv, f, (uchar *)buf, CHORD_TRACEROUTE_LAST, ttl, hops);
-      return 1;
-    } 
-    if ((f = succ_finger(srv)) != NULL) {
-        if (is_between(id, &srv->node.id, &f->node.id) || 
-           equals(id, &f->node.id)) {
-           send_traceroute(srv, f, (uchar *)buf, CHORD_TRACEROUTE_LAST, ttl, 
hops);
-           return 1;
-       }    
-    }
-       
-    /* send to the closest predecessor (that we know about) */
-    f = closest_preceding_finger(srv, id, FALSE);
-    send_traceroute(srv, f, (uchar *)buf, CHORD_TRACEROUTE, ttl, hops); 
-    return 1;
-}
-
-/**********************************************************************/
-
-int process_traceroute_repl(Server *srv, char *buf,
-                           byte ttl, byte hops)
-{
-    CHORD_DEBUG(5, print_process(srv, "process_traceroute_repl", 
-                                &srv->node.id, -1, -1)); 
-    if (hops == 0)
-        return -1;
-    hops--;
-    send_traceroute_repl(srv, (uchar *)buf, ttl, hops, FALSE);
-    return 1;
-}
-
-
-
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include "chord.h"
+
+int process_data(Server *srv, uchar type,
+                 byte ttl, chordID *id, ushort len, uchar *data)
+{
+    Node *np;
+    Finger *pf, *sf;
+
+    CHORD_DEBUG(5, print_process(srv, "process_data", id, -1, -1));
+
+    /* handle request locally? */
+#ifdef SIM_CHORD
+    if (sim_chord_is_local(srv, id)) {
+        /* Upcall goes here... */
+        sim_deliver_data(srv, id, len, data);
+#else
+    if (chord_is_local(id)) {
+        /* Upcall goes here... */
+        chord_deliver(len, data);
+#endif
+        return 1;
+    }
+    if ((type == CHORD_ROUTE_LAST) && ((pf = pred_finger(srv)) != NULL)) {
+        /* the previous hop N believes we are responsible for id,
+         * but we aren't. This means that our predecessor is
+         * a better successor for N. Just pass the packet to our
+         * predecessor. Note that ttl takes care of loops!
+         */
+        send_data(srv, CHORD_ROUTE_LAST, ttl, &pf->node, id, len, data);
+        return 1;
+    }
+    if ((sf = succ_finger(srv)) != NULL) {
+        if (is_between(id, &srv->node.id, &sf->node.id) ||
+            equals(id, &sf->node.id)) {
+            /* according to our info the successor should be responsible
+             * for id; send the packet to the successor.
+             */
+            send_data(srv, CHORD_ROUTE_LAST, ttl, &sf->node, id, len, data);
+            return 1;
+        }
+    }
+    /* send packet to the closest active predecessor (that we know about) */
+    np = closest_preceding_node(srv, id, FALSE);
+    send_data(srv, CHORD_ROUTE, ttl, np, id, len, data);
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_fs(Server *srv, byte ttl, chordID *id, ulong addr, ushort port)
+{
+    Node *succ, *np;
+
+    if (srv->node.addr == addr && srv->node.port == port) {
+        return 1;
+    }
+
+    CHORD_DEBUG(5, print_process(srv, "process_fs", id, addr, port));
+
+    if (succ_finger(srv) == NULL) {
+        send_fs_repl(srv, addr, port,
+                     &srv->node.id, srv->node.addr, srv->node.port);
+        return 0;
+    }
+    succ = &(succ_finger(srv)->node);
+    if (is_between(id, &srv->node.id, &succ->id) || equals(id, &succ->id)) {
+        send_fs_repl(srv, addr, port, &succ->id, succ->addr, succ->port);
+    } else {
+        np = closest_preceding_node(srv, id, FALSE);
+        send_fs(srv, ttl, np->addr, np->port, id, addr, port);
+    }
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_fs_repl(Server *srv, chordID *id, ulong addr, ushort port)
+{
+    int fnew;
+
+    if (srv->node.addr == addr && srv->node.port == port) {
+        return 1;
+    }
+
+    CHORD_DEBUG(5, print_process(srv, "process_fs_repl", id, -1, -1));
+    insert_finger(srv, id, addr, port, &fnew);
+    if (fnew == TRUE) {
+        send_ping(srv, addr, port,
+                  srv->node.addr, srv->node.port, get_current_time());
+    }
+
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_stab(Server *srv, chordID *id, ulong addr, ushort port)
+{
+    Finger *pred = pred_finger(srv);
+    int fnew;
+
+    CHORD_DEBUG(5, print_process(srv, "process_stab", id, addr, port));
+
+    insert_finger(srv, id, addr, port, &fnew);
+    if (pred) {
+        send_stab_repl(srv, addr, port,
+                       &pred->node.id, pred->node.addr, pred->node.port);
+    }
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_stab_repl(Server *srv, chordID *id, ulong addr, ushort port)
+{
+    Finger *succ;
+    int fnew;
+
+    CHORD_DEBUG(5, print_process(srv, "process_stab_repl", id, -1, -1));
+
+    if ((srv->node.addr == addr) && (srv->node.port == port)) {
+        return 1;
+    }
+    insert_finger(srv, id, addr, port, &fnew);
+    succ = succ_finger(srv);
+    send_notify(srv, succ->node.addr, succ->node.port,
+                &srv->node.id, srv->node.addr, srv->node.port);
+    if (fnew == TRUE) {
+        send_ping(srv, addr, port,
+                  srv->node.addr, srv->node.port, get_current_time());
+    }
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_notify(Server *srv, chordID *id, ulong addr, ushort port)
+{
+    int fnew;
+
+    CHORD_DEBUG(5, print_process(srv, "process_notify", id, addr, port));
+    insert_finger(srv, id, addr, port, &fnew);
+    if (fnew == TRUE) {
+        send_ping(srv, addr, port,
+                  srv->node.addr, srv->node.port, get_current_time());
+    }
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_ping(Server *srv, chordID *id, ulong addr, ushort port, ulong time)
+{
+    int fnew;
+    Finger *pred;
+
+    CHORD_DEBUG(5, print_process(srv, "process_ping", id, addr, port));
+    insert_finger(srv, id, addr, port, &fnew);
+    pred = pred_finger(srv);
+    if (fnew == TRUE && ((pred == NULL) ||
+                         (pred && is_between(id, &pred->node.id,
+                                             &srv->node.id)))) {
+        send_ping(srv, addr, port,
+                  srv->node.addr, srv->node.port, get_current_time());
+    }
+
+    send_pong(srv, addr, port, time);
+
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_pong(Server *srv, chordID *id, ulong addr, ushort port, ulong time)
+{
+    Finger *f, *pred, *newpred;
+    ulong new_rtt;
+    int fnew;
+
+    CHORD_DEBUG(5, print_process(srv, "process_pong", id, addr, port));
+    f         = insert_finger(srv, id, addr, port, &fnew);
+    f->npings = 0;
+    new_rtt   = get_current_time() - time; /* takes care of overlow */
+    update_rtt(&f->rtt_avg, &f->rtt_dev, (long) new_rtt);
+
+    pred      = pred_finger(srv);
+    f->status = F_ACTIVE; /* there is a two-way connectivity to this node */
+    newpred   = pred_finger(srv); /* check whether pred has changed, i.e.,
+                                   * f has became the new pred
+                                   */
+    assert(newpred || (pred == newpred));
+
+    if (pred != newpred) {
+        chord_update_range(&newpred->node.id, &srv->node.id);
+    }
+
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_fingers_get(Server *srv, ulong addr, ushort port, Key *key)
+{
+    CHORD_DEBUG(5, print_process(srv, "process_fingers_get", NULL, addr, 
port));
+    if (match_key(key) == 0) {
+        print_server(srv, "[process_fingers_get: invalid key]", "");
+    } else {
+        send_fingers_repl(srv, addr, port);
+    }
+
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_fingers_repl(Server *srv, uchar ret_code)
+{
+    /* this process should be never invoked by the i3 server,
+     * as CHORD_FINGERS_REPL is always sent to the client
+     */
+    CHORD_DEBUG(5, print_process(srv, "process_fingers_repl", NULL, 0, 0));
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_traceroute(Server *srv, chordID *id, char *buf,
+                       uchar type, byte ttl, byte hops)
+{
+    Finger *f;
+
+    CHORD_DEBUG(5, print_process(srv, "process_traceroute", id, -1, -1));
+
+    assert(ttl);
+    ttl--;
+
+    /* handle request locally? */
+#ifdef SIM_CHORD
+    if (sim_chord_is_local(srv, id) || (ttl == 0)) {
+        send_traceroute_repl(srv, buf, ttl, hops, (hops ? FALSE : TRUE));
+#else
+    if (chord_is_local(id) || (ttl == 0)) {
+        send_traceroute_repl(srv, (uchar *) buf, ttl, hops, (hops ? FALSE : 
TRUE));
+#endif
+        return 1;
+    }
+    hops++;
+    if ((type == CHORD_TRACEROUTE_LAST) && (f = pred_finger(srv))) {
+        /* the previous hop N believes we are responsible for id,
+         * but we aren't. This means that our predecessor is
+         * a better successor for N. Just pass the packet to our
+         * predecessor. Note that ttl takes care of loops.
+         */
+        send_traceroute(srv, f, (uchar *) buf, CHORD_TRACEROUTE_LAST, ttl, 
hops);
+        return 1;
+    }
+    if ((f = succ_finger(srv)) != NULL) {
+        if (is_between(id, &srv->node.id, &f->node.id) ||
+            equals(id, &f->node.id)) {
+            send_traceroute(srv, f, (uchar *) buf, CHORD_TRACEROUTE_LAST, ttl, 
hops);
+            return 1;
+        }
+    }
+
+    /* send to the closest predecessor (that we know about) */
+    f = closest_preceding_finger(srv, id, FALSE);
+    send_traceroute(srv, f, (uchar *) buf, CHORD_TRACEROUTE, ttl, hops);
+    return 1;
+}
+
+/**********************************************************************/
+
+int process_traceroute_repl(Server *srv, char *buf,
+                            byte ttl, byte hops)
+{
+    CHORD_DEBUG(5, print_process(srv, "process_traceroute_repl",
+                                 &srv->node.id, -1, -1));
+    if (hops == 0) {
+        return -1;
+    }
+    hops--;
+    send_traceroute_repl(srv, (uchar *) buf, ttl, hops, FALSE);
+    return 1;
+}

=== modified file 'i3/chord/sendpkt.c'
--- i3/chord/sendpkt.c  2009-12-11 22:49:11 +0000
+++ i3/chord/sendpkt.c  2010-02-11 11:49:47 +0000
@@ -1,194 +1,189 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <assert.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include "chord.h"
-
-void send_data(Server *srv, uchar type, byte ttl, Node *np, chordID *id, 
-              ushort n, uchar *data)
-{
-    byte buf[BUFSIZE];
-
-    CHORD_DEBUG(5, print_send(srv, "send_data", id, np->addr, np->port)); 
-    send_raw(srv, np->addr, np->port, pack_data(buf, type, 
-                                               ttl, id, n, data), buf);
-}
-
-/**********************************************************************/
-
-void send_fs(Server *srv, byte ttl, ulong to_addr, ushort to_port,
-            chordID *id, ulong addr, ushort port)
-{
-  byte buf[BUFSIZE];
-
-  CHORD_DEBUG(5, print_send(srv, "send_fs", id, to_addr, to_port)); 
-  send_raw(srv, to_addr, to_port, pack_fs(buf, ttl, id, addr, port), buf); 
-}
-
-/**********************************************************************/
-
-void send_fs_repl(Server *srv, ulong to_addr, ushort to_port,
-                 chordID *id, ulong addr, ushort port)
-{
-  byte buf[BUFSIZE];
-
-  CHORD_DEBUG(5, print_send(srv, "send_fs_repl", id, to_addr, to_port)); 
-  send_raw(srv, to_addr, to_port, pack_fs_repl(buf, id, addr, port), buf);
-}
-
-/**********************************************************************/
-
-void send_stab(Server *srv, ulong to_addr, ushort to_port,
-              chordID *id, ulong addr, ushort port)
-{
-  byte buf[BUFSIZE];
-
-  CHORD_DEBUG(5, print_send(srv, "send_stab", id, to_addr, to_port)); 
-  send_raw(srv, to_addr, to_port, pack_stab(buf, id, addr, port), buf);
-}
-
-/**********************************************************************/
-
-void send_stab_repl(Server *srv, ulong to_addr, ushort to_port,
-                   chordID *id, ulong addr, ushort port)
-{
-  byte buf[BUFSIZE];
-
-  CHORD_DEBUG(5, print_send(srv, "send_stab_repl", id, to_addr, to_port)); 
-  send_raw(srv, to_addr, to_port, pack_stab_repl(buf, id, addr, port), buf);
-}
-
-/**********************************************************************/
-
-void send_notify(Server *srv, ulong to_addr, ushort to_port,
-                chordID *id, ulong addr, ushort port)
-{
-  byte buf[BUFSIZE];
-
-  CHORD_DEBUG(5, print_send(srv, "send_notify", id, to_addr, to_port)); 
-  send_raw(srv, to_addr, to_port, pack_notify(buf, id, addr, port), buf);
-}
-
-/**********************************************************************/
-
-void send_ping(Server *srv, ulong to_addr, ushort to_port,
-              ulong addr, ushort port, ulong time)
-{
-  byte buf[BUFSIZE];
-
-  CHORD_DEBUG(5, print_send(srv, "send_ping", 
-                           &srv->node.id, to_addr, to_port)); 
-  send_raw(srv, to_addr, to_port, 
-          pack_ping(buf, &srv->node.id, addr, port, time), buf);
-}
-
-/**********************************************************************/
-
-void send_pong(Server *srv, ulong to_addr, ushort to_port, ulong time)     
-{
-  byte buf[BUFSIZE];
-
-  CHORD_DEBUG(5, print_send(srv, "send_pong", 
-                           &srv->node.id, to_addr, to_port)); 
-  send_raw(srv, to_addr, to_port, 
-          pack_pong(buf, &srv->node.id, 
-                    srv->node.addr, srv->node.port, time), buf);
-}
-
-
-/**********************************************************************/
-
-void send_fingers_get(Server *srv, ulong to_addr, ushort to_port,
-                     ulong addr, ushort port, Key *key)
-{
-  byte buf[BUFSIZE];
-
-  CHORD_DEBUG(5, print_send(srv, "send_fingers_get", NULL, to_addr, to_port)); 
-  send_raw(srv, to_addr, to_port, 
-          pack_fingers_get(buf, addr, port, key), buf);
-}
-
-/**********************************************************************/
-
-void send_fingers_repl(Server *srv, ulong to_addr, ushort to_port)
-{
-  byte buf[BUFSIZE];
-
-  CHORD_DEBUG(5, print_send(srv, "send_fingers_repl", 
-                           &srv->node.id, to_addr, to_port)); 
-  send_raw(srv, to_addr, to_port, 
-          pack_fingers_repl(buf, srv), buf);
-}
-
-
-
-/**********************************************************************/
-
-void send_traceroute(Server *srv, Finger *f, uchar *buf, uchar type, 
-                    byte ttl, byte hops)
-{
-  CHORD_DEBUG(5, print_send(srv, "send_traceroute", &srv->node.id, -1, -1)); 
-  send_raw(srv, f->node.addr, f->node.port, 
-          pack_traceroute(buf, srv, f, type, ttl, hops), buf);
-}
-
-
-/**********************************************************************/
-
-void send_traceroute_repl(Server *srv, uchar *buf, int ttl, 
-                         int hops, int one_hop)
-{
-  ulong  to_addr; 
-  ushort to_port;
-  int    n;
-
-  CHORD_DEBUG(5, print_send(srv, "send_traceroute_repl", 
-                           &srv->node.id, -1, -1)); 
-  n = pack_traceroute_repl(buf, srv, ttl, hops, &to_addr, &to_port, one_hop);
-  send_raw(srv, to_addr, to_port, n, buf);
-}
-
-
-
-/**********************************************************************/
-
-#ifdef SIM_CHORD
-
-/* send_raw: send datagram to remote addr:port */
-void send_raw(Server *srv, in_addr_t addr, in_port_t port, int n, uchar *buf)
-{
-  /* XXX */
-  //if ((srv->node.addr + addr) % 9 == 1)
-  //  return;
-  /* XXX */
-
-  sim_send_raw(srv, addr, port, n, buf);
-}
-
-#else
-
-/* send_raw: send datagram to remote addr:port */
-void send_raw(Server *srv, in_addr_t addr, in_port_t port, int n, uchar *buf)
-{
-    struct sockaddr_in dest;
-
-    memset(&dest, 0, sizeof(dest));
-    dest.sin_family = AF_INET;
-    dest.sin_port = htons(port);
-    dest.sin_addr.s_addr = htonl(addr);
-
-    if (sendto(srv->out_sock, buf, n, 0, (struct sockaddr *) &dest,
-              sizeof(dest)) < 0)
-        weprintf("sendto failed:"); /* ignore errors for now */
-}
-
-#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include "chord.h"
+
+void send_data(Server *srv, uchar type, byte ttl, Node *np, chordID *id,
+               ushort n, uchar *data)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_data", id, np->addr, np->port));
+    send_raw(srv, np->addr, np->port, pack_data(buf, type,
+                                                ttl, id, n, data), buf);
+}
+
+/**********************************************************************/
+
+void send_fs(Server *srv, byte ttl, ulong to_addr, ushort to_port,
+             chordID *id, ulong addr, ushort port)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_fs", id, to_addr, to_port));
+    send_raw(srv, to_addr, to_port, pack_fs(buf, ttl, id, addr, port), buf);
+}
+
+/**********************************************************************/
+
+void send_fs_repl(Server *srv, ulong to_addr, ushort to_port,
+                  chordID *id, ulong addr, ushort port)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_fs_repl", id, to_addr, to_port));
+    send_raw(srv, to_addr, to_port, pack_fs_repl(buf, id, addr, port), buf);
+}
+
+/**********************************************************************/
+
+void send_stab(Server *srv, ulong to_addr, ushort to_port,
+               chordID *id, ulong addr, ushort port)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_stab", id, to_addr, to_port));
+    send_raw(srv, to_addr, to_port, pack_stab(buf, id, addr, port), buf);
+}
+
+/**********************************************************************/
+
+void send_stab_repl(Server *srv, ulong to_addr, ushort to_port,
+                    chordID *id, ulong addr, ushort port)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_stab_repl", id, to_addr, to_port));
+    send_raw(srv, to_addr, to_port, pack_stab_repl(buf, id, addr, port), buf);
+}
+
+/**********************************************************************/
+
+void send_notify(Server *srv, ulong to_addr, ushort to_port,
+                 chordID *id, ulong addr, ushort port)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_notify", id, to_addr, to_port));
+    send_raw(srv, to_addr, to_port, pack_notify(buf, id, addr, port), buf);
+}
+
+/**********************************************************************/
+
+void send_ping(Server *srv, ulong to_addr, ushort to_port,
+               ulong addr, ushort port, ulong time)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_ping",
+                              &srv->node.id, to_addr, to_port));
+    send_raw(srv, to_addr, to_port,
+             pack_ping(buf, &srv->node.id, addr, port, time), buf);
+}
+
+/**********************************************************************/
+
+void send_pong(Server *srv, ulong to_addr, ushort to_port, ulong time)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_pong",
+                              &srv->node.id, to_addr, to_port));
+    send_raw(srv, to_addr, to_port,
+             pack_pong(buf, &srv->node.id,
+                       srv->node.addr, srv->node.port, time), buf);
+}
+
+/**********************************************************************/
+
+void send_fingers_get(Server *srv, ulong to_addr, ushort to_port,
+                      ulong addr, ushort port, Key *key)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_fingers_get", NULL, to_addr, 
to_port));
+    send_raw(srv, to_addr, to_port,
+             pack_fingers_get(buf, addr, port, key), buf);
+}
+
+/**********************************************************************/
+
+void send_fingers_repl(Server *srv, ulong to_addr, ushort to_port)
+{
+    byte buf[BUFSIZE];
+
+    CHORD_DEBUG(5, print_send(srv, "send_fingers_repl",
+                              &srv->node.id, to_addr, to_port));
+    send_raw(srv, to_addr, to_port,
+             pack_fingers_repl(buf, srv), buf);
+}
+
+/**********************************************************************/
+
+void send_traceroute(Server *srv, Finger *f, uchar *buf, uchar type,
+                     byte ttl, byte hops)
+{
+    CHORD_DEBUG(5, print_send(srv, "send_traceroute", &srv->node.id, -1, -1));
+    send_raw(srv, f->node.addr, f->node.port,
+             pack_traceroute(buf, srv, f, type, ttl, hops), buf);
+}
+
+/**********************************************************************/
+
+void send_traceroute_repl(Server *srv, uchar *buf, int ttl,
+                          int hops, int one_hop)
+{
+    ulong to_addr;
+    ushort to_port;
+    int n;
+
+    CHORD_DEBUG(5, print_send(srv, "send_traceroute_repl",
+                              &srv->node.id, -1, -1));
+    n = pack_traceroute_repl(buf, srv, ttl, hops, &to_addr, &to_port, one_hop);
+    send_raw(srv, to_addr, to_port, n, buf);
+}
+
+/**********************************************************************/
+
+#ifdef SIM_CHORD
+
+/* send_raw: send datagram to remote addr:port */
+void send_raw(Server *srv, in_addr_t addr, in_port_t port, int n, uchar *buf)
+{
+    /* XXX */
+    //if ((srv->node.addr + addr) % 9 == 1)
+    //  return;
+    /* XXX */
+
+    sim_send_raw(srv, addr, port, n, buf);
+}
+
+#else
+
+/* send_raw: send datagram to remote addr:port */
+void send_raw(Server *srv, in_addr_t addr, in_port_t port, int n, uchar *buf)
+{
+    struct sockaddr_in dest;
+
+    memset(&dest, 0, sizeof(dest));
+    dest.sin_family      = AF_INET;
+    dest.sin_port        = htons(port);
+    dest.sin_addr.s_addr = htonl(addr);
+
+    if (sendto(srv->out_sock, buf, n, 0, (struct sockaddr *) &dest,
+               sizeof(dest)) < 0) {
+        weprintf("sendto failed:"); /* ignore errors for now */
+    }
+}
+
+#endif

=== modified file 'i3/chord/stabilize.c'
--- i3/chord/stabilize.c        2010-01-12 12:35:31 +0000
+++ i3/chord/stabilize.c        2010-02-11 11:49:47 +0000
@@ -1,387 +1,399 @@
-#include <stdlib.h>
-#include <sys/time.h>
-#include <string.h>
-#include <signal.h>
-#include <assert.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "chord.h"
-#include "../utils/gen_utils.h"
-
-/* Global variable that is a pointer to srv in chord main */
-Server *srv_ref;
-
-/* local functions */
-static void fix_fingers(Server *srv);
-static void fix_succs_preds(Server *srv);
-static void ping(Server *srv);
-static void clean_finger_list(Server *srv);
-
-/* stabilize: the following things are done periodically
- *  - stabilize successor by asking for its predecessor
- *  - fix one backup successor 
- *  - fix one proper finger 
- *  - ping one node in the finger list (the finger list includes 
- *    the backup successors, the proper fingers and the predecessor)
- *  - ping any node in the finger list that has not replied to the
- *    previous ping
- */
-
-#define CHORD_CLEAN_PERIOD 60
-
-void stabilize(Server *srv)
-{
-  static int idx = 0, i;
-  Finger *succ, *pred;
-
-  /* Hack to get around the fact that parameters
-   * cannot be passed when setting signal timers 
-   */
-#ifndef SIM_CHORD
-  srv = srv_ref;
-  /* Set next stabilize time */
-  do {
-    srv->next_stabilize_us += STABILIZE_PERIOD;
-  } while(srv->next_stabilize_us <= wall_time());
-#endif
-
-  /* While there is no successor, we fix that! */
-  if (srv->head_flist == NULL) {
-#ifndef SIM_CHORD
-    for (i = 0; ((i < nknown) && (i < MAX_SIMJOIN)); i++) {
-      send_fs(srv, DEF_TTL, well_known[i].addr, well_known[i].port,
-             &srv->node.id, srv->node.addr, srv->node.port);
-      send_ping(srv, well_known[i].addr, well_known[i].port,
-               srv->node.addr, srv->node.port, get_current_time());
-    }
-#else
-    {
-      Server *s;
-#define SRV_PRESENT 2
-      /* join by contacting two nodes, already in the system */
-      for (i = 0; i < 2; i++) {
-       s = get_random_server(srv->node.addr, SRV_PRESENT);
-       if (s != NULL) {
-         send_fs(srv, DEF_TTL, s->node.addr, s->node.port,
-                 &srv->node.id, srv->node.addr, srv->node.port);
-         send_ping(srv, s->node.addr, s->node.port,
-                   srv->node.addr, srv->node.port, get_current_time());
-       }
-      }
-    }
-#endif
-    return;
-  }
-  
-  /* ping one node in the finger list; these nodes are 
-   * pinged in a round robin fashion. 
-   * In ddition, ping all nodes which have not replyed to previous pings
-   */
-  ping(srv);
-
-  /* stabilize successor */
-  if ((succ = succ_finger(srv)) == NULL)
-    return;
-  send_stab(srv, succ->node.addr, succ->node.port,
-           &srv->node.id, srv->node.addr, srv->node.port);
-
-  /* ping predecessor. Normally we should hear from our
-   * predecessor via the stabilize message. However, if we
-   * cannot communicate with our true predecessor, our predecessor
-   * will be another node, so we need to ping it...
-   */
-#define PERIOD_PING_PRED 5
-  if (idx % PERIOD_PING_PRED == 0) {
-    pred = pred_finger(srv);
-    assert(pred);
-    send_ping(srv, pred->node.addr, pred->node.port, 
-             srv->node.addr, srv->node.port, get_current_time());
-  } 
-
-  /* fix one backup successor and predessors in a round-robin fashion */
-  fix_succs_preds(srv);
-
-  /* fix one proper finger that is not a backup successor; 
-   * backup successors are fixed in a round-robin fashion 
-   */
-  fix_fingers(srv);
-
-  if ((idx++) % CHORD_CLEAN_PERIOD == 0) {
-    /* remove all nodes in the finger list that are neither (1)
-     * backup successors, nor (2) proper fingers, and nor (3) backup 
-     * predecessors
-     */
-    clean_finger_list(srv);
-  }
-}
-
-
-/**********************************************************************/
-
-void fix_fingers(Server *srv)
-{
-  Finger *f, *succ = succ_finger(srv);
-  chordID id = successor(srv->node.id, srv->to_fix_finger);
-  chordID to_id = successor(srv->node.id, NFINGERS-1);
-
-  CHORD_DEBUG(5, print_fun(srv, "fix_finger", &id));
-
-  /* Only loop across most significant fingers */
-  if (is_between(&id, &srv->node.id, &succ->node.id) ||
-      (srv->to_fix_finger == 0)) {
-    /* the problem we are trying to solve here is the one of
-     * loopy graphs, i.e., graphs that are locally consistent
-     * but globally inconsistent (see the Chord TR). Loopy
-     * graphs are quite common in the Internet where the
-     * communication is not necessary symmetric or transitive
-     * (i.e., A can reach B and C, but B cannot reach C).
-     * Loopy graphs cause in lookup failures, as two loops
-     * that originate in different parts of the ring can reach
-     * different targets.
-     * To alleviate loopy graph we ask a random node to resolve 
-     * a query to a random id between us and our successor. 
-     */
-    random_between(&srv->node.id, &succ->node.id, &id);
-#ifdef SIM_CHORD
-    Server *s;
-    s = get_random_server(srv->node.addr, SRV_PRESENT);
-    if (s) {
-      send_fs(srv, DEF_TTL, s->node.addr, s->node.port,
-             &id, srv->node.addr, srv->node.port);
-    } 
-#else
-    Node *n;
-    n = &well_known[random() % nknown];
-    if (nknown) 
-      send_fs(srv, DEF_TTL, n->addr, n->port,
-             &id, srv->node.addr, srv->node.port);
-#endif // SIM_CHORD
-    srv->to_fix_finger = NFINGERS-1;
-  } else
-    srv->to_fix_finger--;
-
-  /* ask one of our fingers to find the proper finger corresponding to id. 
-   * preferable this is a far away finger, that share as little routing
-   * information as possible with us
-   */
-  if ((f = closest_preceding_finger(srv, &to_id, FALSE)) == NULL) 
-    /* settle for successor... */
-    f = succ;
-  if (f) {
-    send_fs(srv, DEF_TTL, f->node.addr, f->node.port,
-           &id, srv->node.addr, srv->node.port);
-
-    /* once in a while try to get a better predecessor, as well */
-    if (srv->to_fix_finger == NFINGERS-1) {
-      if (PRED(srv)) {
-       random_between(&(PRED(srv)->node.id), &srv->node.id, &id);
-       send_fs(srv, DEF_TTL, f->node.addr, f->node.port,
-               &id, srv->node.addr, srv->node.port);
-      }
-    }
-  }   
-}
-
-
-/**********************************************************************/
-/* fix backup successors and predecessors in a round-robin fashion    */
-/**********************************************************************/
-
-void fix_succs_preds(Server *srv)
-{
-  int k;
-  Finger *f, *succ;
-  chordID id;
-
-  CHORD_DEBUG(5, print_fun(srv, "fix_successors", &f->node.id));
-
-  if (succ_finger(srv) == NULL)
-    return;
-
-  /* find the next successor to be fixed... */
-  for (f = succ_finger(srv), k = 0; 
-       (k < srv->to_fix_backup) && f->next; 
-       k++, f = f->next);
-  /* ... no more successors to be fixed; restart */
-  if (f->next == NULL) {
-    srv->to_fix_backup = 0;
-    return;
-  }
-
-  /* find f's successor */
-  id = successor(f->node.id, 0);
-  send_fs(srv, DEF_TTL, f->node.addr, f->node.port, 
-         &id, srv->node.addr, srv->node.port);
-  succ = f;
-
-  /* now fix predecessors; this is not part of the Chord protocol,
-   * but in pactice having more than one predecessor is more robust
-   *
-   * use same index (to_fix_backup) to fix predecessor, as well. Note 
-   * that here we assume that NPREDECESSORS <= NSUCCESSORS
-   */
-  for (f = pred_finger(srv), k = 0; (k < NPREDECESSORS) && f->prev; 
-       k++, f = f->prev) {
-    if (f->next == NULL)
-      /* f is our known predecessor; if there is a node between our 
-       * predecessor and us, we'll get it during the next stabilization 
-       * round
-       */
-      continue;
-    if (f == succ)
-      /* f is both a successor and predecessor */
-      break;
-    if (k == srv->to_fix_backup) {
-      /* fix predecessor */
-      random_between(&f->node.id, &f->next->node.id, &id);
-      send_fs(srv, DEF_TTL, f->node.addr, f->node.port, 
-             &id, srv->node.addr, srv->node.port);
-      break;
-    }
-  }
-
-  srv->to_fix_backup++;
-  if (srv->to_fix_backup >= NSUCCESSORS)
-    srv->to_fix_backup = 0;
-}
-
-/************************************************************************/
-
-void ping(Server *srv)
-{
-  int i;
-  struct in_addr ia;
-  Finger *f, *f_next, *f_pinged = NULL;
-
-  /* ping every finger who is still waiting for reply to a previous ping,
-   * and the to_ping-th finger in the list 
-   */
-  for (f = srv->head_flist, i = 0; f; i++) {
-
-    if (f->npings >= PING_THRESH) {
-#define ADDR_STR_LEN   16
-      char srv_addr[ADDR_STR_LEN+1];
-      char dropped_addr[ADDR_STR_LEN+1];
-      ia.s_addr = htonl(srv->node.addr);
-      strncpy( srv_addr, inet_ntoa(ia), ADDR_STR_LEN );
-      ia.s_addr = htonl(f->node.addr);
-      strncpy( dropped_addr, inet_ntoa(ia), ADDR_STR_LEN );
-      
-#ifdef SIM_CHORD
-      // print_fun(srv, "dropping finger", &f->node.id); 
-#else
-      weprintf("dropping finger[%d] %s:%d (at %s:%d)\n",
-              i, dropped_addr, f->node.port,
-              srv_addr, srv->node.port);
-#endif
-      f_next = f->next;
-      remove_finger(srv, f);
-    } else {
-      if (f->npings || (srv->to_ping == i)) {
-       f->npings++;
-       send_ping(srv, f->node.addr, f->node.port, 
-                 srv->node.addr, srv->node.port, get_current_time());
-       if (srv->to_ping == i) 
-         f_pinged = f;
-      }
-      f_next = f->next;
-    }
-    f = f_next;
-  }
-
-  if (!f_pinged || !(f_pinged->next))
-    srv->to_ping = 0;
-  else
-    srv->to_ping++;
-}
-
-/**********************************************************************
- * keep only (1) backup successors, (2) proper fingers, and (3) predecessor;
- * remove anything else from finger list
- ***********************************************************************/
-
-void clean_finger_list(Server *srv)
-{
-  Finger *f, *f_lastsucc, *f_lastpred, *f_tmp;
-  int     k;
-  chordID id;
-
-  /* skip successor list */
-  for (f = srv->head_flist, k = 0; f && (k < NSUCCESSORS-1); f = f->next, k++);
-  if (f == NULL || f->next == NULL)
-    return;
-  f_lastsucc = f;
-
-  /* start from the tail and skip predecessors */
-  for (f = srv->tail_flist, k = 0; k < NPREDECESSORS-1; f = f->prev, k++) {
-    if (f == f_lastsucc)
-      /* finger list contains only of backup successors and predecesor */
-      return;
-  }
-  f_lastpred = f;
-  f = f_lastpred->prev;        /* First disposable finger */
-
-  /* keep only unique (proper) fingers */
-  for (k = NFINGERS - 1; k >= 0; k--) {
-
-    if (f == f_lastsucc)
-      return;
-
-    /* compute srv.id + 2^k */
-    id = successor(srv->node.id, k);
-
-    if (is_between(&id, &f_lastpred->node.id, &srv->node.id) ||
-       equals(&id, &f_lastpred->node.id)) {
-      /* proper finger for id is one of the (backup) predecessors */
-      continue;
-    }
-    
-    if (is_between(&id, &srv->node.id, &f_lastsucc->node.id) ||
-       equals(&id, &srv->node.id))
-      /* proper finger for id is one of the (backup) successors */
-      break;
-
-    if (is_between(&f->node.id, &srv->node.id, &id)) {
-      /* f cannot be a proper finger for id, because it
-       * is between current node and id; try next finger
-       */
-      continue;
-    }
-    
-    /* f is a possible proper finger for id */
-    while (1) {
-      if (f->prev == NULL || f == f_lastsucc)
-       return;
-      if (is_between(&f->prev->node.id, &id, &f->node.id) ||
-         equals(&f->prev->node.id, &id)) {
-       /* this is not a proper finger (i.e., f's predecessor
-        * is between id and f), so remove f 
-        */
-       f_tmp = f;
-       f = f->prev;
-       remove_finger(srv, f_tmp);
-      } else {
-       /* f is a proper finger */
-       f = f->prev;
-       break;
-      }
-    }
-  }
-}
-  
-
-
-/**********************************************************************/
-/* set_stabilize_timer: Set first stabilize time (to now).           */
-/**********************************************************************/
-
-void set_stabilize_timer(void)
-{
-    /* do not use get_current_time(), because we need the 
-     * resolution of uint64_t 
-     */
-    srv_ref->next_stabilize_us = wall_time();
-}
-
+#include <stdlib.h>
+#include <sys/time.h>
+#include <string.h>
+#include <signal.h>
+#include <assert.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "chord.h"
+#include "../utils/gen_utils.h"
+
+/* Global variable that is a pointer to srv in chord main */
+Server *srv_ref;
+
+/* local functions */
+static void fix_fingers(Server *srv);
+static void fix_succs_preds(Server *srv);
+static void ping(Server *srv);
+static void clean_finger_list(Server *srv);
+
+/* stabilize: the following things are done periodically
+ *  - stabilize successor by asking for its predecessor
+ *  - fix one backup successor
+ *  - fix one proper finger
+ *  - ping one node in the finger list (the finger list includes
+ *    the backup successors, the proper fingers and the predecessor)
+ *  - ping any node in the finger list that has not replied to the
+ *    previous ping
+ */
+
+#define CHORD_CLEAN_PERIOD 60
+
+void stabilize(Server *srv)
+{
+    static int idx = 0, i;
+    Finger *succ, *pred;
+
+    /* Hack to get around the fact that parameters
+     * cannot be passed when setting signal timers
+     */
+#ifndef SIM_CHORD
+    srv = srv_ref;
+    /* Set next stabilize time */
+    do {
+        srv->next_stabilize_us += STABILIZE_PERIOD;
+    } while (srv->next_stabilize_us <= wall_time());
+#endif
+
+    /* While there is no successor, we fix that! */
+    if (srv->head_flist == NULL) {
+#ifndef SIM_CHORD
+        for (i = 0; ((i < nknown) && (i < MAX_SIMJOIN)); i++) {
+            send_fs(srv, DEF_TTL, well_known[i].addr, well_known[i].port,
+                    &srv->node.id, srv->node.addr, srv->node.port);
+            send_ping(srv, well_known[i].addr, well_known[i].port,
+                      srv->node.addr, srv->node.port, get_current_time());
+        }
+#else
+        {
+            Server *s;
+#define SRV_PRESENT 2
+            /* join by contacting two nodes, already in the system */
+            for (i = 0; i < 2; i++) {
+                s = get_random_server(srv->node.addr, SRV_PRESENT);
+                if (s != NULL) {
+                    send_fs(srv, DEF_TTL, s->node.addr, s->node.port,
+                            &srv->node.id, srv->node.addr, srv->node.port);
+                    send_ping(srv, s->node.addr, s->node.port,
+                              srv->node.addr, srv->node.port, 
get_current_time());
+                }
+            }
+        }
+#endif
+        return;
+    }
+
+    /* ping one node in the finger list; these nodes are
+     * pinged in a round robin fashion.
+     * In ddition, ping all nodes which have not replyed to previous pings
+     */
+    ping(srv);
+
+    /* stabilize successor */
+    if ((succ = succ_finger(srv)) == NULL) {
+        return;
+    }
+    send_stab(srv, succ->node.addr, succ->node.port,
+              &srv->node.id, srv->node.addr, srv->node.port);
+
+    /* ping predecessor. Normally we should hear from our
+     * predecessor via the stabilize message. However, if we
+     * cannot communicate with our true predecessor, our predecessor
+     * will be another node, so we need to ping it...
+     */
+#define PERIOD_PING_PRED 5
+    if (idx % PERIOD_PING_PRED == 0) {
+        pred = pred_finger(srv);
+        assert(pred);
+        send_ping(srv, pred->node.addr, pred->node.port,
+                  srv->node.addr, srv->node.port, get_current_time());
+    }
+
+    /* fix one backup successor and predessors in a round-robin fashion */
+    fix_succs_preds(srv);
+
+    /* fix one proper finger that is not a backup successor;
+     * backup successors are fixed in a round-robin fashion
+     */
+    fix_fingers(srv);
+
+    if ((idx++) % CHORD_CLEAN_PERIOD == 0) {
+        /* remove all nodes in the finger list that are neither (1)
+         * backup successors, nor (2) proper fingers, and nor (3) backup
+         * predecessors
+         */
+        clean_finger_list(srv);
+    }
+}
+
+/**********************************************************************/
+
+void fix_fingers(Server *srv)
+{
+    Finger *f, *succ = succ_finger(srv);
+    chordID id    = successor(srv->node.id, srv->to_fix_finger);
+    chordID to_id = successor(srv->node.id, NFINGERS - 1);
+
+    CHORD_DEBUG(5, print_fun(srv, "fix_finger", &id));
+
+    /* Only loop across most significant fingers */
+    if (is_between(&id, &srv->node.id, &succ->node.id) ||
+        (srv->to_fix_finger == 0)) {
+        /* the problem we are trying to solve here is the one of
+         * loopy graphs, i.e., graphs that are locally consistent
+         * but globally inconsistent (see the Chord TR). Loopy
+         * graphs are quite common in the Internet where the
+         * communication is not necessary symmetric or transitive
+         * (i.e., A can reach B and C, but B cannot reach C).
+         * Loopy graphs cause in lookup failures, as two loops
+         * that originate in different parts of the ring can reach
+         * different targets.
+         * To alleviate loopy graph we ask a random node to resolve
+         * a query to a random id between us and our successor.
+         */
+        random_between(&srv->node.id, &succ->node.id, &id);
+#ifdef SIM_CHORD
+        Server *s;
+        s = get_random_server(srv->node.addr, SRV_PRESENT);
+        if (s) {
+            send_fs(srv, DEF_TTL, s->node.addr, s->node.port,
+                    &id, srv->node.addr, srv->node.port);
+        }
+#else
+        Node *n;
+        n = &well_known[random() % nknown];
+        if (nknown) {
+            send_fs(srv, DEF_TTL, n->addr, n->port,
+                    &id, srv->node.addr, srv->node.port);
+        }
+#endif // SIM_CHORD
+        srv->to_fix_finger = NFINGERS - 1;
+    } else {
+        srv->to_fix_finger--;
+    }
+
+    /* ask one of our fingers to find the proper finger corresponding to id.
+     * preferable this is a far away finger, that share as little routing
+     * information as possible with us
+     */
+    if ((f = closest_preceding_finger(srv, &to_id, FALSE)) == NULL) {
+        /* settle for successor... */
+        f = succ;
+    }
+    if (f) {
+        send_fs(srv, DEF_TTL, f->node.addr, f->node.port,
+                &id, srv->node.addr, srv->node.port);
+
+        /* once in a while try to get a better predecessor, as well */
+        if (srv->to_fix_finger == NFINGERS - 1) {
+            if (PRED(srv)) {
+                random_between(&(PRED(srv)->node.id), &srv->node.id, &id);
+                send_fs(srv, DEF_TTL, f->node.addr, f->node.port,
+                        &id, srv->node.addr, srv->node.port);
+            }
+        }
+    }
+}
+
+/**********************************************************************/
+/* fix backup successors and predecessors in a round-robin fashion    */
+/**********************************************************************/
+
+void fix_succs_preds(Server *srv)
+{
+    int k;
+    Finger *f, *succ;
+    chordID id;
+
+    CHORD_DEBUG(5, print_fun(srv, "fix_successors", &f->node.id));
+
+    if (succ_finger(srv) == NULL) {
+        return;
+    }
+
+    /* find the next successor to be fixed... */
+    for (f = succ_finger(srv), k = 0;
+         (k < srv->to_fix_backup) && f->next;
+         k++, f = f->next) {
+        ;
+    }
+    /* ... no more successors to be fixed; restart */
+    if (f->next == NULL) {
+        srv->to_fix_backup = 0;
+        return;
+    }
+
+    /* find f's successor */
+    id   = successor(f->node.id, 0);
+    send_fs(srv, DEF_TTL, f->node.addr, f->node.port,
+            &id, srv->node.addr, srv->node.port);
+    succ = f;
+
+    /* now fix predecessors; this is not part of the Chord protocol,
+     * but in pactice having more than one predecessor is more robust
+     *
+     * use same index (to_fix_backup) to fix predecessor, as well. Note
+     * that here we assume that NPREDECESSORS <= NSUCCESSORS
+     */
+    for (f = pred_finger(srv), k = 0; (k < NPREDECESSORS) && f->prev;
+         k++, f = f->prev) {
+        if (f->next == NULL) {
+            /* f is our known predecessor; if there is a node between our
+             * predecessor and us, we'll get it during the next stabilization
+             * round
+             */
+            continue;
+        }
+        if (f == succ) {
+            /* f is both a successor and predecessor */
+            break;
+        }
+        if (k == srv->to_fix_backup) {
+            /* fix predecessor */
+            random_between(&f->node.id, &f->next->node.id, &id);
+            send_fs(srv, DEF_TTL, f->node.addr, f->node.port,
+                    &id, srv->node.addr, srv->node.port);
+            break;
+        }
+    }
+
+    srv->to_fix_backup++;
+    if (srv->to_fix_backup >= NSUCCESSORS) {
+        srv->to_fix_backup = 0;
+    }
+}
+
+/************************************************************************/
+
+void ping(Server *srv)
+{
+    int i;
+    struct in_addr ia;
+    Finger *f, *f_next, *f_pinged = NULL;
+
+    /* ping every finger who is still waiting for reply to a previous ping,
+     * and the to_ping-th finger in the list
+     */
+    for (f = srv->head_flist, i = 0; f; i++) {
+        if (f->npings >= PING_THRESH) {
+#define ADDR_STR_LEN    16
+            char srv_addr[ADDR_STR_LEN + 1];
+            char dropped_addr[ADDR_STR_LEN + 1];
+            ia.s_addr = htonl(srv->node.addr);
+            strncpy( srv_addr, inet_ntoa(ia), ADDR_STR_LEN );
+            ia.s_addr = htonl(f->node.addr);
+            strncpy( dropped_addr, inet_ntoa(ia), ADDR_STR_LEN );
+
+#ifdef SIM_CHORD
+            // print_fun(srv, "dropping finger", &f->node.id);
+#else
+            weprintf("dropping finger[%d] %s:%d (at %s:%d)\n",
+                     i, dropped_addr, f->node.port,
+                     srv_addr, srv->node.port);
+#endif
+            f_next = f->next;
+            remove_finger(srv, f);
+        } else {
+            if (f->npings || (srv->to_ping == i)) {
+                f->npings++;
+                send_ping(srv, f->node.addr, f->node.port,
+                          srv->node.addr, srv->node.port, get_current_time());
+                if (srv->to_ping == i) {
+                    f_pinged = f;
+                }
+            }
+            f_next = f->next;
+        }
+        f = f_next;
+    }
+
+    if (!f_pinged || !(f_pinged->next)) {
+        srv->to_ping = 0;
+    } else {
+        srv->to_ping++;
+    }
+}
+
+/**********************************************************************
+ * keep only (1) backup successors, (2) proper fingers, and (3) predecessor;
+ * remove anything else from finger list
+ ***********************************************************************/
+
+void clean_finger_list(Server *srv)
+{
+    Finger *f, *f_lastsucc, *f_lastpred, *f_tmp;
+    int k;
+    chordID id;
+
+    /* skip successor list */
+    for (f = srv->head_flist, k = 0; f && (k < NSUCCESSORS - 1); f = f->next, 
k++) {
+        ;
+    }
+    if (f == NULL || f->next == NULL) {
+        return;
+    }
+    f_lastsucc = f;
+
+    /* start from the tail and skip predecessors */
+    for (f = srv->tail_flist, k = 0; k < NPREDECESSORS - 1; f = f->prev, k++) {
+        if (f == f_lastsucc) {
+            /* finger list contains only of backup successors and predecesor */
+            return;
+        }
+    }
+    f_lastpred = f;
+    f          = f_lastpred->prev; /* First disposable finger */
+
+    /* keep only unique (proper) fingers */
+    for (k = NFINGERS - 1; k >= 0; k--) {
+        if (f == f_lastsucc) {
+            return;
+        }
+
+        /* compute srv.id + 2^k */
+        id = successor(srv->node.id, k);
+
+        if (is_between(&id, &f_lastpred->node.id, &srv->node.id) ||
+            equals(&id, &f_lastpred->node.id)) {
+            /* proper finger for id is one of the (backup) predecessors */
+            continue;
+        }
+
+        if (is_between(&id, &srv->node.id, &f_lastsucc->node.id) ||
+            equals(&id, &srv->node.id)) {
+            /* proper finger for id is one of the (backup) successors */
+            break;
+        }
+
+        if (is_between(&f->node.id, &srv->node.id, &id)) {
+            /* f cannot be a proper finger for id, because it
+             * is between current node and id; try next finger
+             */
+            continue;
+        }
+
+        /* f is a possible proper finger for id */
+        while (1) {
+            if (f->prev == NULL || f == f_lastsucc) {
+                return;
+            }
+            if (is_between(&f->prev->node.id, &id, &f->node.id) ||
+                equals(&f->prev->node.id, &id)) {
+                /* this is not a proper finger (i.e., f's predecessor
+                 * is between id and f), so remove f
+                 */
+                f_tmp = f;
+                f     = f->prev;
+                remove_finger(srv, f_tmp);
+            } else {
+                /* f is a proper finger */
+                f = f->prev;
+                break;
+            }
+        }
+    }
+}
+
+/**********************************************************************/
+/* set_stabilize_timer: Set first stabilize time (to now).          */
+/**********************************************************************/
+
+void set_stabilize_timer(void)
+{
+    /* do not use get_current_time(), because we need the
+     * resolution of uint64_t
+     */
+    srv_ref->next_stabilize_us = wall_time();
+}

=== modified file 'i3/chord/test.c'
--- i3/chord/test.c     2009-12-11 22:49:11 +0000
+++ i3/chord/test.c     2010-02-11 11:49:47 +0000
@@ -1,10 +1,10 @@
-#include <sys/wait.h>
-#include "chord_api.h"
-
-int main(int argc, char **argv)
-{
-  chord_init(argv[1]);
-  wait(0);
-
-  return 0;
-}
+#include <sys/wait.h>
+#include "chord_api.h"
+
+int main(int argc, char **argv)
+{
+    chord_init(argv[1]);
+    wait(0);
+
+    return 0;
+}

=== modified file 'i3/chord/util.c'
--- i3/chord/util.c     2009-12-11 22:49:11 +0000
+++ i3/chord/util.c     2010-02-11 11:49:47 +0000
@@ -1,522 +1,546 @@
-#include <assert.h>
-#include <ctype.h> 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include "chord.h"
-#include "../utils/gen_utils.h"
-
-#if 0
-/* f_rand: return a random double between 0.0 and 1.0 */
-double f_rand(void)
-{
-    int64_t l, r;
-
-    l = (int64_t) (random() & ((1 << 26) - 1));
-    r = (int64_t) (random() & ((1 << 27) - 1));
-    return ((l << 27) + r) / (double)(1LL << 53);
-}
-
-/**********************************************************************/
-
-/* funif_rand: Return a random number between a and b */
-double funif_rand(double a, double b)
-{
-    return a + (b - a) * f_rand();
-}
-
-/**********************************************************************/
-
-/* n_rand: return a random integer in [0, n),
-   borrowed from Java Random class */
-int n_rand(int n)
-{
-    int bits, val;
-
-    assert(n > 0);   /* n must be positive */
-
-    /* Special case: power of 2 */
-    if ((n & -n) == n)
-       return random() & (n - 1);
-
-    do {
-       bits = random();
-       val = bits % n;
-    } while (bits - val + (n - 1) < 0);
-    return val;
-}
-
-/**********************************************************************/
-
-/* unif_rand: return a random integer number in the interval [a, b) */
-int unif_rand(int a, int b)
-{
-    return a + n_rand(b - a);
-}
-
-/**********************************************************************/
-
-/* getusec: return wall time in usec */
-uint64_t wall_time(void)
-{
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    return tv.tv_sec * 1000000ULL + tv.tv_usec;
-}
-
-/**********************************************************************/
-#endif
-void update_rtt(long *rtt_avg, long *rtt_dev, long new_rtt)
-{
-  long err;
-
-  if (*rtt_avg == 0) {
-    *rtt_avg = new_rtt;
-    *rtt_dev = 0;
-    return;
-  }
-
-  /* use TCP's rtt estimation algorithm */
-  err = new_rtt - *rtt_avg;
-  *rtt_avg += err >> 3;
-  if (err < 0) err = -err;
-  *rtt_dev += (err - *rtt_dev) >> 2;
-}
-    
-
-/**********************************************************************/
-
-/* randID: return a random ID */
-chordID rand_ID(void)
-{
-    chordID id;
-    int i;
-
-    for (i = 0; i < ID_LEN; i++)
-       id.x[i] = (byte)(random() & 0xff);
-    return id;
-}
-
-/**********************************************************************/
-
-/* successorID: id + (1 << n) */
-chordID successor(chordID id, int n)
-{
-    byte old;
-    int i, start;
-
-    assert(n >= 0 && n < NBITS);
-    /* Note id.x[0] is most significant bit */
-    start = ID_LEN-1 - n/8;
-    old = id.x[start];
-    id.x[start] += 1 << (n%8);
-    if (id.x[start] < old)
-       for (i = start-1; i >= 0; i--) {
-           id.x[i]++;
-           if (id.x[i]) break;
-       }
-    return id;
-}
-
-/**********************************************************************/
-
-/* predecessorID: id - (1 << n) */
-chordID predecessor(chordID id, int n)
-{
-    byte old;
-    int i, start;
-
-    assert(n >= 0 && n < NBITS);
-    start = ID_LEN-1 - n/8;
-    old = id.x[start];
-    id.x[start] -= 1 << (n%8);
-    if (id.x[start] > old)
-       for (i = start-1; i >= 0; i--) {
-           if (id.x[i]) {
-               id.x[i]--;
-               break;
-           } else
-               id.x[i]--;
-       }
-    return id;
-}
-
-/**********************************************************************/
-
-/* add: res = a + b (mod 2^n) */
-void add(chordID *a, chordID *b, chordID *res)
-{
-    int carry, i;
-
-    carry = 0;
-    for (i = ID_LEN - 1; i >= 0; i--) {
-       res->x[i] = (a->x[i] + b->x[i] + carry) & 0xff;
-       carry = (a->x[i] + b->x[i] + carry) >> 8;
-    }
-}
-
-/**********************************************************************/
-
-/* subtract: res = a - b (mod 2^n) */
-void subtract(chordID *a, chordID *b, chordID *res)
-{
-    int borrow, i;
-
-    borrow = 0;
-    for (i = ID_LEN - 1; i >= 0; i--) {
-       if (a->x[i] - borrow < b->x[i]) {
-           res->x[i] = 256 + a->x[i] - borrow - b->x[i];
-           borrow = 1;
-       } else {
-           res->x[i] = a->x[i] - borrow - b->x[i];
-           borrow = 0;
-       }
-    }
-}
-
-/**********************************************************************/
-
-chordID random_from(chordID *a)
-{
-    chordID b;
-    int     i, m = random()%10 + 1;
-
-    for (i = 0; i < ID_LEN; i++) {
-        b.x[i] = a->x[i]*m/11;
-    }
-    return b;
-}
-
-/**********************************************************************/
-
-void random_between(chordID *a, chordID *b, chordID *res)
-{
-  chordID r;
-
-  subtract(b, a, res);
-
-  r = random_from(res);
-
-  add(a, &r, res);
-}
-
-/**********************************************************************/
-
-static int msb_tab[256] = {
-    0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
-};
-
-/* msb: most significant bit */
-int
-msb(chordID *x)
-{
-    int i;
-
-    for (i = 0; i < ID_LEN; i++)
-       if (x->x[i])
-           return 8 * i + msb_tab[x->x[i]];
-    return 0;
-}
-
-/**********************************************************************/
-
-/* equals: a == b? */
-int equals(chordID *a, chordID *b)
-{
-    return memcmp(a->x, b->x, sizeof(chordID)) == 0;
-}
-
-/* equals: a == b? */
-int equals_id_str(chordID *a, char *b)
-{
-  chordID idb = atoid(b);
-
-  return memcmp(a->x, idb.x, sizeof(chordID)) == 0;
-}
-
-/**********************************************************************/
-
-int is_zero(chordID *x)
-{
-    static chordID zero;
-    return memcmp(x->x, zero.x, sizeof(chordID)) == 0;
-}
-
-/**********************************************************************/
-
-/* greater: a>b? */
-/*
-static int is_greater(chordID *a, chordID *b)
-{
-    return memcmp(a->x, b->x, sizeof(chordID)) > 0;
-}
-*/
-
-/* less: a<b? */
-static int is_less(chordID *a, chordID *b)
-{
-    return memcmp(a->x, b->x, sizeof(chordID)) < 0;
-}
-
-/* between: is x in (a,b) on circle? */
-int is_between(chordID *x, chordID *a, chordID *b)
-{
-    if (equals(a, b))
-       return !equals(x, a);   /* x is only node not in (x,x) */
-    else if (is_less(a, b))
-       return is_less(a, x) && is_less(x, b);
-    else
-       return is_less(a, x) || is_less(x, b);
-}
-
-/***********************************************/
-int copy_id( chordID *a, chordID *b)
-{
-    int i = 0;
-
-    assert(a);
-    assert(b);
-    for (i = 0; i < sizeof(chordID); i++)
-        a->x[i] = b->x[i];
-    return 1;
-}
-
-/**********************************************************************/
-
-void print_id(FILE *f, chordID *id)
-{
-    int i;
-
-    for (i = 0; i < ID_LEN; i++)
-       fprintf(f, "%02x", id->x[i]);
-}
-
-/**********************************************************************/
-
-
-/**********************************************************************/
-
-static unsigned char todigit(char ch)
-{
-    if (isdigit((int) ch))
-       return (ch - '0');
-    else
-       return (10 + ch - 'a');
-}
-
-chordID atoid(const char *str)
-{
-    chordID id;
-    int i;
-    
-    assert(strlen(str) == 2*ID_LEN);
-    for (i = 0; i < ID_LEN; i++)
-       id.x[ i ] = (todigit(str[2*i]) << 4) | todigit(str[2*i+1]);
-    return id;
-}
-
-/**********************************************************************/
-
-enum {
-    MULTIPLIER = 31       /* for hash() */
-};
-
-/* hash: compute hash value for ID */
-unsigned hash(chordID *id, unsigned n)
-{
-    unsigned h;
-    int i;
-
-    h = 0;
-    for (i = 0; i < ID_LEN; i++)
-       h = MULTIPLIER * h + id->x[ i ];
-
-    return h % n;
-}
-
-
-/* hash: compute hash value for ID */
-int match_key(Key *key)
-{
-  int i;
-
-  for (i = 0; i < NumKeys; i++) {
-    if (memcmp((char *)&key->x[0], (char *)&KeyArray[i].x[0], KEY_LEN) == 0) {
-      return 1;
-    }
-  }
-  return 0;
-}
-
-/***********************************************************************/
-
-void print_chordID(chordID *id)
-{
-  int i;
-
-  for (i = 0; i < ID_LEN; i++)
-    printf("%02x", id->x[i]);
-}
-
-/***********************************************************************/
-
-void print_two_chordIDs(char *preffix, chordID *id1, char *middle,
-                       chordID *id2, char *suffix)
-{
-  assert(preffix && id1 && middle && id2 && suffix);
-  printf("%s", preffix);
-  print_chordID(id1);
-  printf("%s", middle); 
-  print_chordID(id2);
-  printf("%s", suffix); 
-}
-
-/***********************************************************************/
-
-void print_three_chordIDs(char *preffix, chordID *id1, 
-                         char *middle1, chordID *id2, 
-                         char *middle2, chordID *id3,
-                         char *suffix)
-{
-  assert(preffix && id1 && middle1 && id2 && middle2 && id3 && suffix);
-  printf("%s", preffix);
-  print_chordID(id1);
-  printf("%s", middle1); 
-  print_chordID(id2);
-  printf("%s", middle2); 
-  print_chordID(id3);
-  printf("%s", suffix); 
-}
-
-
-/***********************************************************************/
-
-void print_node(Node *node, char *prefix, char *suffix)
-{
-  struct in_addr ia;
-
-  printf("%s", prefix);
-  print_chordID(&node->id);
-  ia.s_addr = htonl(node->addr);
-  printf(", %s, %d%s", inet_ntoa(ia), node->port, suffix);
-}
-
-void print_finger(Finger *f, char *prefix, char *suffix)
-{
-  printf("%sFinger:", prefix);
-  print_node(&f->node, "<", ">");
-#ifndef CIL 
-  printf(" (status = %d, npings = %d, rtt = %ld/%ld) %s", 
-        f->status, f->npings, f->rtt_avg, f->rtt_dev, suffix);
-#else
-  printf(" (status = %d, npings = %d, rtt = %ld/%ld)%s", 
-        f->status, f->npings, f->rtt_avg, f->rtt_dev, suffix);
-#endif  
-}
-
-
-void print_finger_list(Finger *fhead, char *prefix, char *suffix)
-{
-  int i;
-  Finger *f;
-
-  printf("%s", prefix);
-  for (f = fhead, i = 0; f; f = f->next, i++) {
-    printf("  [%d] ", i);
-    print_finger(f, "", "\n");
-  }
-  printf("%s", suffix);
-}
-
-void print_server(Server *s, char *prefix, char *suffix)
-{
-  printf("---------------%s---------------\n", prefix);
-  print_node(&s->node, "[", "]\n");
-  print_finger_list(s->head_flist, "  Finger list:\n", "\n");
-  printf("---------------%s---------------\n", suffix);
-}
-
-
-void print_process(Server *srv, char *process_type, chordID *id,
-                  ulong addr, ushort port)
-{
-#define TYPE_LEN 16
-  int i = TYPE_LEN - strlen(process_type);
-
-  printf("[%s]", process_type);
-  if (i > 0) for (; i; i--) printf(" ");
-
-  printf(" (");
-   if (id)
-    print_chordID(id);
-  else
-    printf("null");
-   printf(") ");
-  print_node(&srv->node, " <", ">");
-  if (addr == -1)
-    printf(" <----- <,>");
-  else
-    printf(" <----- <%ld, %d>", addr, port);
-  print_current_time(" Time:", "\n");
-}
-
-void print_send(Server *srv, char *send_type, chordID *id,
-               ulong addr, ushort port)
-{
-  int i = TYPE_LEN - strlen(send_type);
-
-  printf("[%s]", send_type);
-  if (i > 0) for (; i; i--) printf(" ");
-
-  printf(" (");
-   if (id)
-    print_chordID(id);
-  else
-    printf("null");
-   printf(") ");
-  print_node(&srv->node, " <", ">");
-  if (addr == -1)
-    printf(" -----> <,>");
-  else
-    printf(" -----> <%ld, %d>", addr, port);
-  print_current_time(" Time:", "\n");
-}
-
-void print_fun(Server *srv, char *fun_name, chordID *id)
-{
-  printf("%s: ", fun_name);
-  print_chordID(&srv->node.id);
-  printf(" > ");
-  print_chordID(id);
-  print_current_time(" @ ", "\n");
-}
-
-ulong get_current_time()
-{
-#ifdef SIM_CHORD
-  return (ulong)sim_get_time();
-#else
-  return (ulong)wall_time();
-#endif
-}
-
-void print_current_time(char *prefix, char *suffix)
-{
-#ifdef SIM_CHORD
-  printf("%s%f%s", prefix, sim_get_time(), suffix);
-#else
-  printf("%s%lld%s", prefix, (long long int)wall_time(), suffix);
-#endif
-}
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "chord.h"
+#include "../utils/gen_utils.h"
+
+#if 0
+/* f_rand: return a random double between 0.0 and 1.0 */
+double f_rand(void)
+{
+    int64_t l, r;
+
+    l = (int64_t) (random() & ((1 << 26) - 1));
+    r = (int64_t) (random() & ((1 << 27) - 1));
+    return ((l << 27) + r) / (double) (1LL << 53);
+}
+
+/**********************************************************************/
+
+/* funif_rand: Return a random number between a and b */
+double funif_rand(double a, double b)
+{
+    return a + (b - a) * f_rand();
+}
+
+/**********************************************************************/
+
+/* n_rand: return a random integer in [0, n),
+ * borrowed from Java Random class */
+int n_rand(int n)
+{
+    int bits, val;
+
+    assert(n > 0);   /* n must be positive */
+
+    /* Special case: power of 2 */
+    if ((n & - n) == n) {
+        return random() & (n - 1);
+    }
+
+    do {
+        bits = random();
+        val  = bits % n;
+    } while (bits - val + (n - 1) < 0);
+    return val;
+}
+
+/**********************************************************************/
+
+/* unif_rand: return a random integer number in the interval [a, b) */
+int unif_rand(int a, int b)
+{
+    return a + n_rand(b - a);
+}
+
+/**********************************************************************/
+
+/* getusec: return wall time in usec */
+uint64_t wall_time(void)
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000ULL + tv.tv_usec;
+}
+
+/**********************************************************************/
+#endif
+void update_rtt(long *rtt_avg, long *rtt_dev, long new_rtt)
+{
+    long err;
+
+    if (*rtt_avg == 0) {
+        *rtt_avg = new_rtt;
+        *rtt_dev = 0;
+        return;
+    }
+
+    /* use TCP's rtt estimation algorithm */
+    err       = new_rtt - *rtt_avg;
+    *rtt_avg += err >> 3;
+    if (err < 0) {
+        err = -err;
+    }
+    *rtt_dev += (err - *rtt_dev) >> 2;
+}
+
+/**********************************************************************/
+
+/* randID: return a random ID */
+chordID rand_ID(void)
+{
+    chordID id;
+    int i;
+
+    for (i = 0; i < ID_LEN; i++) {
+        id.x[i] = (byte) (random() & 0xff);
+    }
+    return id;
+}
+
+/**********************************************************************/
+
+/* successorID: id + (1 << n) */
+chordID successor(chordID id, int n)
+{
+    byte old;
+    int i, start;
+
+    assert(n >= 0 && n < NBITS);
+    /* Note id.x[0] is most significant bit */
+    start        = ID_LEN - 1 - n / 8;
+    old          = id.x[start];
+    id.x[start] += 1 << (n % 8);
+    if (id.x[start] < old) {
+        for (i = start - 1; i >= 0; i--) {
+            id.x[i]++;
+            if (id.x[i]) {
+                break;
+            }
+        }
+    }
+    return id;
+}
+
+/**********************************************************************/
+
+/* predecessorID: id - (1 << n) */
+chordID predecessor(chordID id, int n)
+{
+    byte old;
+    int i, start;
+
+    assert(n >= 0 && n < NBITS);
+    start        = ID_LEN - 1 - n / 8;
+    old          = id.x[start];
+    id.x[start] -= 1 << (n % 8);
+    if (id.x[start] > old) {
+        for (i = start - 1; i >= 0; i--) {
+            if (id.x[i]) {
+                id.x[i]--;
+                break;
+            } else {
+                id.x[i]--;
+            }
+        }
+    }
+    return id;
+}
+
+/**********************************************************************/
+
+/* add: res = a + b (mod 2^n) */
+void add(chordID *a, chordID *b, chordID *res)
+{
+    int carry, i;
+
+    carry = 0;
+    for (i = ID_LEN - 1; i >= 0; i--) {
+        res->x[i] = (a->x[i] + b->x[i] + carry) & 0xff;
+        carry     = (a->x[i] + b->x[i] + carry) >> 8;
+    }
+}
+
+/**********************************************************************/
+
+/* subtract: res = a - b (mod 2^n) */
+void subtract(chordID *a, chordID *b, chordID *res)
+{
+    int borrow, i;
+
+    borrow = 0;
+    for (i = ID_LEN - 1; i >= 0; i--) {
+        if (a->x[i] - borrow < b->x[i]) {
+            res->x[i] = 256 + a->x[i] - borrow - b->x[i];
+            borrow    = 1;
+        } else {
+            res->x[i] = a->x[i] - borrow - b->x[i];
+            borrow    = 0;
+        }
+    }
+}
+
+/**********************************************************************/
+
+chordID random_from(chordID *a)
+{
+    chordID b;
+    int i, m = random() % 10 + 1;
+
+    for (i = 0; i < ID_LEN; i++) {
+        b.x[i] = a->x[i] * m / 11;
+    }
+    return b;
+}
+
+/**********************************************************************/
+
+void random_between(chordID *a, chordID *b, chordID *res)
+{
+    chordID r;
+
+    subtract(b, a, res);
+
+    r = random_from(res);
+
+    add(a, &r, res);
+}
+
+/**********************************************************************/
+
+static int msb_tab[256] = {
+    0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 4,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 5, 5,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 6, 6,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 6, 6,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7
+};
+
+/* msb: most significant bit */
+int msb(chordID *x)
+{
+    int i;
+
+    for (i = 0; i < ID_LEN; i++) {
+        if (x->x[i]) {
+            return 8 * i + msb_tab[x->x[i]];
+        }
+    }
+    return 0;
+}
+
+/**********************************************************************/
+
+/* equals: a == b? */
+int equals(chordID *a, chordID *b)
+{
+    return memcmp(a->x, b->x, sizeof(chordID)) == 0;
+}
+
+/* equals: a == b? */
+int equals_id_str(chordID *a, char *b)
+{
+    chordID idb = atoid(b);
+
+    return memcmp(a->x, idb.x, sizeof(chordID)) == 0;
+}
+
+/**********************************************************************/
+
+int is_zero(chordID *x)
+{
+    static chordID zero;
+    return memcmp(x->x, zero.x, sizeof(chordID)) == 0;
+}
+
+/**********************************************************************/
+
+/* greater: a>b? */
+/*
+ * static int is_greater(chordID *a, chordID *b)
+ * {
+ *  return memcmp(a->x, b->x, sizeof(chordID)) > 0;
+ * }
+ */
+
+/* less: a<b? */
+static int is_less(chordID *a, chordID *b)
+{
+    return memcmp(a->x, b->x, sizeof(chordID)) < 0;
+}
+
+/* between: is x in (a,b) on circle? */
+int is_between(chordID *x, chordID *a, chordID *b)
+{
+    if (equals(a, b)) {
+        return !equals(x, a);   /* x is only node not in (x,x) */
+    } else if (is_less(a, b))                                                  
              {
+        return is_less(a, x) && is_less(x, b);
+    } else {
+        return is_less(a, x) || is_less(x, b);
+    }
+}
+
+/***********************************************/
+int copy_id( chordID *a, chordID *b)
+{
+    int i = 0;
+
+    assert(a);
+    assert(b);
+    for (i = 0; i < sizeof(chordID); i++) {
+        a->x[i] = b->x[i];
+    }
+    return 1;
+}
+
+/**********************************************************************/
+
+void print_id(FILE *f, chordID *id)
+{
+    int i;
+
+    for (i = 0; i < ID_LEN; i++) {
+        fprintf(f, "%02x", id->x[i]);
+    }
+}
+
+/**********************************************************************/
+
+
+/**********************************************************************/
+
+static unsigned char todigit(char ch)
+{
+    if (isdigit((int) ch)) {
+        return ch - '0';
+    } else {
+        return 10 + ch - 'a';
+    }
+}
+
+chordID atoid(const char *str)
+{
+    chordID id;
+    int i;
+
+    assert(strlen(str) == 2 * ID_LEN);
+    for (i = 0; i < ID_LEN; i++) {
+        id.x[ i ] = (todigit(str[2 * i]) << 4) | todigit(str[2 * i + 1]);
+    }
+    return id;
+}
+
+/**********************************************************************/
+
+enum {
+    MULTIPLIER = 31       /* for hash() */
+};
+
+/* hash: compute hash value for ID */
+unsigned hash(chordID *id, unsigned n)
+{
+    unsigned h;
+    int i;
+
+    h = 0;
+    for (i = 0; i < ID_LEN; i++) {
+        h = MULTIPLIER * h + id->x[ i ];
+    }
+
+    return h % n;
+}
+
+/* hash: compute hash value for ID */
+int match_key(Key *key)
+{
+    int i;
+
+    for (i = 0; i < NumKeys; i++) {
+        if (memcmp((char *) &key->x[0], (char *) &KeyArray[i].x[0], KEY_LEN) 
== 0) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+/***********************************************************************/
+
+void print_chordID(chordID *id)
+{
+    int i;
+
+    for (i = 0; i < ID_LEN; i++) {
+        printf("%02x", id->x[i]);
+    }
+}
+
+/***********************************************************************/
+
+void print_two_chordIDs(char *preffix, chordID *id1, char *middle,
+                        chordID *id2, char *suffix)
+{
+    assert(preffix && id1 && middle && id2 && suffix);
+    printf("%s", preffix);
+    print_chordID(id1);
+    printf("%s", middle);
+    print_chordID(id2);
+    printf("%s", suffix);
+}
+
+/***********************************************************************/
+
+void print_three_chordIDs(char *preffix, chordID *id1,
+                          char *middle1, chordID *id2,
+                          char *middle2, chordID *id3,
+                          char *suffix)
+{
+    assert(preffix && id1 && middle1 && id2 && middle2 && id3 && suffix);
+    printf("%s", preffix);
+    print_chordID(id1);
+    printf("%s", middle1);
+    print_chordID(id2);
+    printf("%s", middle2);
+    print_chordID(id3);
+    printf("%s", suffix);
+}
+
+/***********************************************************************/
+
+void print_node(Node *node, char *prefix, char *suffix)
+{
+    struct in_addr ia;
+
+    printf("%s", prefix);
+    print_chordID(&node->id);
+    ia.s_addr = htonl(node->addr);
+    printf(", %s, %d%s", inet_ntoa(ia), node->port, suffix);
+}
+
+void print_finger(Finger *f, char *prefix, char *suffix)
+{
+    printf("%sFinger:", prefix);
+    print_node(&f->node, "<", ">");
+#ifndef CIL
+    printf(" (status = %d, npings = %d, rtt = %ld/%ld) %s",
+           f->status, f->npings, f->rtt_avg, f->rtt_dev, suffix);
+#else
+    printf(" (status = %d, npings = %d, rtt = %ld/%ld)%s",
+           f->status, f->npings, f->rtt_avg, f->rtt_dev, suffix);
+#endif
+}
+
+void print_finger_list(Finger *fhead, char *prefix, char *suffix)
+{
+    int i;
+    Finger *f;
+
+    printf("%s", prefix);
+    for (f = fhead, i = 0; f; f = f->next, i++) {
+        printf("  [%d] ", i);
+        print_finger(f, "", "\n");
+    }
+    printf("%s", suffix);
+}
+
+void print_server(Server *s, char *prefix, char *suffix)
+{
+    printf("---------------%s---------------\n", prefix);
+    print_node(&s->node, "[", "]\n");
+    print_finger_list(s->head_flist, "  Finger list:\n", "\n");
+    printf("---------------%s---------------\n", suffix);
+}
+
+void print_process(Server *srv, char *process_type, chordID *id,
+                   ulong addr, ushort port)
+{
+#define TYPE_LEN 16
+    int i = TYPE_LEN - strlen(process_type);
+
+    printf("[%s]", process_type);
+    if (i > 0) {
+        for (; i; i--) {
+            printf(" ");
+        }
+    }
+
+    printf(" (");
+    if (id) {
+        print_chordID(id);
+    } else {
+        printf("null");
+    }
+    printf(") ");
+    print_node(&srv->node, " <", ">");
+    if (addr == -1) {
+        printf(" <----- <,>");
+    } else {
+        printf(" <----- <%ld, %d>", addr, port);
+    }
+    print_current_time(" Time:", "\n");
+}
+
+void print_send(Server *srv, char *send_type, chordID *id,
+                ulong addr, ushort port)
+{
+    int i = TYPE_LEN - strlen(send_type);
+
+    printf("[%s]", send_type);
+    if (i > 0) {
+        for (; i; i--) {
+            printf(" ");
+        }
+    }
+
+    printf(" (");
+    if (id) {
+        print_chordID(id);
+    } else {
+        printf("null");
+    }
+    printf(") ");
+    print_node(&srv->node, " <", ">");
+    if (addr == -1) {
+        printf(" -----> <,>");
+    } else {
+        printf(" -----> <%ld, %d>", addr, port);
+    }
+    print_current_time(" Time:", "\n");
+}
+
+void print_fun(Server *srv, char *fun_name, chordID *id)
+{
+    printf("%s: ", fun_name);
+    print_chordID(&srv->node.id);
+    printf(" > ");
+    print_chordID(id);
+    print_current_time(" @ ", "\n");
+}
+
+ulong get_current_time()
+{
+#ifdef SIM_CHORD
+    return (ulong) sim_get_time();
+#else
+    return (ulong) wall_time();
+#endif
+}
+
+void print_current_time(char *prefix, char *suffix)
+{
+#ifdef SIM_CHORD
+    printf("%s%f%s", prefix, sim_get_time(), suffix);
+#else
+    printf("%s%lld%s", prefix, (long long int) wall_time(), suffix);
+#endif
+}

=== modified file 'i3/i3/debug_fns.h'
--- i3/i3/debug_fns.h   2010-01-19 09:28:42 +0000
+++ i3/i3/debug_fns.h   2010-02-11 11:49:47 +0000
@@ -13,50 +13,53 @@
 
 
 #ifndef I3_PRINT_DEBUG
-       /**
-        * This macro is used to print debugging information. 
-        * The message is printed only if the current debugging level is
-        * greater than that of the level specified in the macro call.
-        */
+/**
+ * This macro is used to print debugging information.
+ * The message is printed only if the current debugging level is
+ * greater than that of the level specified in the macro call.
+ */
       #if 0 // We turn off the i3 debuging instead we will use HIP_DEBUG
-         #define I3_PRINT_DEBUG(debugLevel, msg, ... )  if(debugLevel <= 
I3_CURRENT_DEBUG_LEVEL) { printf("[Line:%d in file:%s] ", __LINE__, __FILE__); 
printf(msg, ##__VA_ARGS__);}
-      #endif 
-
-      #define I3_PRINT_DEBUG(debugLevel, ... ) if(debugLevel <= 
I3_CURRENT_DEBUG_LEVEL) HIP_DEBUG(__VA_ARGS__)
-
-
-      #define I3_PRINT_DEBUG0  I3_PRINT_DEBUG
-      #define I3_PRINT_DEBUG1  I3_PRINT_DEBUG
-      #define I3_PRINT_DEBUG2  I3_PRINT_DEBUG
-      #define I3_PRINT_DEBUG3  I3_PRINT_DEBUG
-      #define I3_PRINT_DEBUG4  I3_PRINT_DEBUG
-      #define I3_PRINT_DEBUG5  I3_PRINT_DEBUG
-      #define I3_PRINT_DEBUG6  I3_PRINT_DEBUG
-      #define I3_PRINT_DEBUG7  I3_PRINT_DEBUG
+         #define I3_PRINT_DEBUG(debugLevel, msg, ... )  if (debugLevel <= 
I3_CURRENT_DEBUG_LEVEL) { printf("[Line:%d in file:%s] ", __LINE__, __FILE__); 
printf(msg, ## __VA_ARGS__); }
+      #endif
+
+      #define I3_PRINT_DEBUG(debugLevel, ... ) if (debugLevel <= 
I3_CURRENT_DEBUG_LEVEL) \
+        HIP_DEBUG(__VA_ARGS__)
+
+
+      #define I3_PRINT_DEBUG0   I3_PRINT_DEBUG
+      #define I3_PRINT_DEBUG1   I3_PRINT_DEBUG
+      #define I3_PRINT_DEBUG2   I3_PRINT_DEBUG
+      #define I3_PRINT_DEBUG3   I3_PRINT_DEBUG
+      #define I3_PRINT_DEBUG4   I3_PRINT_DEBUG
+      #define I3_PRINT_DEBUG5   I3_PRINT_DEBUG
+      #define I3_PRINT_DEBUG6   I3_PRINT_DEBUG
+      #define I3_PRINT_DEBUG7   I3_PRINT_DEBUG
 
 #endif  //I3_PRINT_DEBUG
 
 /**
-  * This macro is used to print messages irrespective of debug level.
-  * These are messages are not for debugging, but for giving information
-  * to the user.
-  */
+ * This macro is used to print messages irrespective of debug level.
+ * These are messages are not for debugging, but for giving information
+ * to the user.
+ */
 #ifndef I3_PRINT_INFO
 
    #if 0
-      #define I3_PRINT_INFO(infoLevel, msg, ...) if(infoLevel <= 
I3_CURRENT_INFO_LEVEL) printf(msg, ##__VA_ARGS__)
+      #define I3_PRINT_INFO(infoLevel, msg, ...) if (infoLevel <= 
I3_CURRENT_INFO_LEVEL) \
+        printf(msg, ## __VA_ARGS__)
    #endif
 
-   #define I3_PRINT_INFO(infoLevel, ... ) if(infoLevel <= 
I3_CURRENT_INFO_LEVEL) HIP_INFO(__VA_ARGS__) 
+   #define I3_PRINT_INFO(infoLevel, ... ) if (infoLevel <= 
I3_CURRENT_INFO_LEVEL) \
+        HIP_INFO(__VA_ARGS__)
 
    #define I3_PRINT_INFO0       I3_PRINT_INFO
-   #define I3_PRINT_INFO1      I3_PRINT_INFO
-   #define I3_PRINT_INFO2      I3_PRINT_INFO
-   #define I3_PRINT_INFO3      I3_PRINT_INFO
-   #define I3_PRINT_INFO4      I3_PRINT_INFO
-   #define I3_PRINT_INFO5      I3_PRINT_INFO
-   #define I3_PRINT_INFO6      I3_PRINT_INFO
-   #define I3_PRINT_INFO7      I3_PRINT_INFO
+   #define I3_PRINT_INFO1       I3_PRINT_INFO
+   #define I3_PRINT_INFO2       I3_PRINT_INFO
+   #define I3_PRINT_INFO3       I3_PRINT_INFO
+   #define I3_PRINT_INFO4       I3_PRINT_INFO
+   #define I3_PRINT_INFO5       I3_PRINT_INFO
+   #define I3_PRINT_INFO6       I3_PRINT_INFO
+   #define I3_PRINT_INFO7       I3_PRINT_INFO
 
 #endif //I3_PRINT_INFO
 

=== modified file 'i3/i3/i3.h'
--- i3/i3/i3.h  2009-12-11 22:49:11 +0000
+++ i3/i3/i3.h  2010-02-11 11:49:47 +0000
@@ -1,456 +1,447 @@
-/***************************************************************************
-                          i3.h  -  description
-                             -------------------
-    begin                : Son Nov 17 2002
-    email                : wehrle@xxxxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef I3_H
-#define I3_H 
- 
-#include <sys/types.h>
-#ifdef _WIN32
-    #include "../utils/fwint.h"
-#endif
-#include "../utils/netwrap.h"
-#ifdef __APPLE__
-#include <inttypes.h>  // Need uint8_t
-#include <sys/time.h>  // Need timeval
-#endif
-#include <assert.h>
-
-/* CLIENT_API_DEPRECIATED specifies whether the old client api is used */
-//#define  CLIENT_API_DEPRECIATED
-
-#ifndef TRUE
-#define TRUE  1
-#define FALSE 0
-#endif  
-
-#define CHAR_BITS 8
-
-// first byte in a packet sent to an i3 server
-//   - normal i3 packet --> version number
-//   - i3 ping packet --> I3_PING_PACKET
-
-// note that i3 ping packets are not i3 packets; ping responses
-// should be from a different process, but for fatesharing reasons
-// implemented together 
-#define I3_v01          0x10
-#define I3_PING_PKT    0x01
-
-#define I3_DATA         0x10
-#define I3_OPTION_LIST  0x20
-#define I3_FIRST_HOP    0x40
-
-#define I3_ADDR_TYPE_STACK 0x10
-#define I3_ADDR_TYPE_IPv4  0x20
-#define I3_ADDR_TYPE_IPv6  0x30
-#define I3_ADDR_TYPE_IPv4_NAT 0x40
-
-#define I3_ID_TYPE_PUBLIC      0x10
-#define I3_ID_TYPE_PRIVATE     0x20
-//#define I3_ID_TYPE_UNCONSTRAINED 0x30
-#define I3_ID_TYPE_UNKNOWN      0x40
-
-#define I3_OPT_SENDER                  0x01
-#define I3_OPT_TRIGGER_INSERT          0x02
-#define I3_OPT_TRIGGER_CHALLENGE       0x03
-#define I3_OPT_TRIGGER_ACK             0x04
-#define I3_OPT_TRIGGER_REMOVE          0x05
-#define I3_OPT_TRIGGER_NOT_PRESENT     0x06
-#define I3_OPT_REQUEST_FOR_CACHE       0x07
-#define I3_OPT_CACHE_ADDR              0x08
-#define I3_OPT_FORCE_CACHE_ADDR                0x09
-#define I3_OPT_CONSTRAINT_FAILED       0x10
-#define I3_OPT_ROUTE_BROKEN            0x11
-#define I3_OPT_REQUEST_FOR_CACHE_SHORTCUT 0x12
-#define I3_OPT_CACHE_SHORTCUT_ADDR      0x13
-#define I3_OPT_CACHE_DEST_ADDR          0x14
-#define I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR 0x15
-#define I3_OPT_DESTINATION              0x20
-#define I3_OPT_TRIGGER_RATELIMIT       0x30
-
-/* flags associated to trigger */
-#define I3_TRIGGER_FLAG_ALLOW_SHORTCUT  0x1
-#define I3_TRIGGER_FLAG_RATE_LIMIT      0x2
-
-#define I3_ERR_INVALID_VER       -1
-#define I3_ERR_INVALID_FLAGS     -2
-#define I3_ERR_PKT_LEN_TOO_SHORT -3
-#define I3_ERR_INVALID_STACK     -4
-#define I3_ERR_INVALID_ADDR      -5
-#define I3_ERR_INVALID_OPTLIST   -6
-#define I3_ERR_INVALID_OPTION    -7
-
-#define L_CONSTRAINT 0
-#define R_CONSTRAINT 1
-
-#define NEWS_INSTRUMENT 1
-
-#if NEWS_INSTRUMENT
-// 2 options for instrumenting i3 servers
-// maybe modified later for cleanliness
-#define I3_OPT_LOG_PACKET              0x0A
-#define I3_OPT_APPEND_TS               0x0B
-#define MAX_NEWS_OPTS                  2
-#endif
-
-#define OK              1
-#define ERROR           0
-
-#define INDENT_CONST    2      /* just for printing data nice for debugging */
-#define INDENT_BUF_LEN  100    /* just for printing data nice for debugging */
-
-
-/******************************
- ** Type of an i3-id         **
- ******************************/
-
-#define ID_LEN                 32  /* in bytes */
-#define ID_LEN_BITS            256 /* in bits, i.e., ID_LEN_BITS = ID_LEN*8 */
-#define MIN_PREFIX_LEN         192 /* minimum prefix length that has to match 
*/
-
-#define PREFIX_LEN      8
-#define KEY_LEN                16  /* length of key in bytes */
-
-#define PREFIX_ID(id)  (id.x)
-#define KEY_ID(id)     (id.x + PREFIX_LEN)
-#define KEY_ID_PTR(id) (id->x + PREFIX_LEN)
-#define SUFFIX_ID(id)  (id.x + SUFFIX_LEN)
-typedef struct 
-{
-  uint8_t x[ID_LEN];
-} ID;
-
-typedef struct
-{
-  uint8_t x[KEY_LEN];
-} Key;
-
-/******************************
- ** structure of an i3-stack **
- ******************************/
-        
-#define I3_MAX_STACK_LEN 15
-typedef struct i3_stack {
-  int len; /* # of IDs in the stack */
-  ID *ids;
-} i3_stack;
-
-
-/********************************
- ** structure of an i3 address **
- ********************************/
-#ifndef CCURED
- #define __SELECTEDWHEN(x)
- #define __SELECTOR(x)
- #define __RTTI
-#endif
-typedef struct i3_addr {
-  char type;      
-  union
-  {
-                      /* I3_ADDR_TYPE_STACK */
-    i3_stack *stack        __SELECTEDWHEN("type" == I3_ADDR_TYPE_STACK);
-    
-    struct            /* I3_ADDR_TYPE_IPv4 */
-    {
-      struct in_addr   addr;
-      uint16_t         port;
-    } v4                    __SELECTEDWHEN("type" == I3_ADDR_TYPE_IPv4);
-
-    /* v4_nat is used to store all the information required to support
-     * NAT hosts:
-     *  - (host_addr, host_port) is the address of the host, which
-     *    can be behind NAT
-     *  - (nat_addr, nat_port) is the address assigned by the NAT to the host
-     *  - (i3srv_addr, i3srv_port) is the address of the first i3 server
-     *    to which the host sends packets
-     */
-    struct
-    {
-      struct in_addr host_addr;
-      uint16_t       host_port;
-      struct in_addr nat_addr;
-      uint16_t       nat_port;
-      struct in_addr i3srv_addr;
-      uint16_t       i3srv_port;
-      
-    } v4_nat             __SELECTEDWHEN("type" == I3_ADDR_TYPE_IPv4_NAT);
-
-
-#ifndef __CYGWIN__   
-    struct            /* I3_ADDR_TYPE_IPv6 */
-    {
-      struct in6_addr  addr;
-      uint16_t         port;
-    } v6                     __SELECTEDWHEN("type" == I3_ADDR_TYPE_IPv6);
-#endif
-  } t;
-} i3_addr;
-
-
-typedef struct token_bucket {
-#define TOKEN_BUCKET_PACKET 0
-#define TOKEN_BUCKET_BYTE   1
-  char type; /* specifies whether units are "packets" or "bytes" */
-  uint32_t depth; /* token depth (bytes or packets) */
-  uint32_t r; /* long term rate (Bps or pps) */
-  uint32_t R; /* maximum rate (Bps or pps) */
-  /* only the first three fields are packed in packet;
-   * the following two fields are temporar variables
-   * used to implement the token bucket functionality
-   */
-  uint32_t tokens; /* actual number of tokens in the bucket (bytes or packets)
-                   * Note: "tokens" is never larger than "depth" 
-                   */
-  uint64_t last_time; /* time since the previous packet has been 
-                      * received (usec) 
-                      */
-} token_bucket;
-
-#define NONCE_LEN  16
-typedef struct i3_trigger {
-  ID           id;
-  uint8_t       flags;  /* possible flags:I3_TRIGGER_FLAG_ALLOW_SHORTCUT (0x1)
-                        * I3_TRIGGER_FLAG_RATE_LIMIT (0x2)
-                        */
-  uint16_t     prefix_len; /* packet ID should match trigID in the first
-                            max(prefix_len, MIN_PREFIX_LEN) bits or more */
-  char         nonce[NONCE_LEN];
-  i3_addr      *to;    
-  Key          key;
-  token_bucket  *tb; /* this is set only if I3_TRIGGER_FLAG_RATE_LIMIT is set*/
-} i3_trigger;
-
-
-/************************************
- ** i3_option_entry data structure **
- ************************************/
-
-typedef struct i3_option
-{
-  char type;      
-  union
-  {
-    /* sender address where to send a reply (type = I3_OPT_SENDER)
-     */
-    i3_addr   *ret_addr  __SELECTEDWHEN("type" == I3_OPT_SENDER);
-    
-    /* sender address where to send a reply (type = I3_OPT_SENDER)
-     */
-    i3_addr   *dst_addr  __SELECTEDWHEN("type" == I3_OPT_DESTINATION);
-    
-    /* trigger insertion and challenge 
-     * (type = I3_OPT_TRIGGER_INSERT, I3_OPT_TRIGGER_CHALLENGE,
-     * I3_OPT_TRIGGER_ACK, I3_OPT_TRIGGER_REMOVE,
-     * I3_OPT_CACHE_ADDR, I3_OPT_CACHE_SHORTCUT_ADDR,
-     * I3_OPT_CACHE_DEST_ADDR,
-     * I3_OPT_CONSTRAINT_FAILED, I3_OPT_ROUTE_BROKEN)
-     *
-     * When I3_OPT_CACHE_ADDR is used, trigger->to represents the 
-     * the address suggested by the i3 server (e.g., its own address)
-     * where client should send data and control messages addressed to
-     * any identifier that shares MIN_PREFIX_LEN bits with trigger->id.
-     * Thus, this option allows the client to cache the address of a server
-     * responsible for a certain identifier.
-     * When I3_OPT_CACHE_SHORTCUT_ADDR is used, trigger->to represents the 
-     * the address of the end host. This option is sent directly to the 
-     * receiver. The receiver can see whether the sender is behind a NAT
-     * by comparing the IP source address of the packet and the IP address
-     * in trigger->to.
-     */
-    i3_trigger *trigger __SELECTEDWHEN("type" == I3_OPT_TRIGGER_INSERT || \
-                                       "type" == I3_OPT_TRIGGER_CHALLENGE || \
-                                      "type" == I3_OPT_TRIGGER_ACK || \
-                                      "type" == I3_OPT_TRIGGER_REMOVE || \
-                                      "type" == I3_OPT_CACHE_ADDR || \
-                                      "type" == I3_OPT_CACHE_DEST_ADDR || \
-                                      "type" == I3_OPT_CACHE_SHORTCUT_ADDR ||\
-                                      "type" == I3_OPT_CONSTRAINT_FAILED\
-                                      "type" == I3_OPT_ROUTE_BROKEN);
-
-    /* id to which the reply refers to (type = I3_OPT_TRIGGER_NOT_PRESENT,
-     * I3_OPT_REQUEST_FOR_CACHE, I3_OPT_TRIGGER_RATELIMIT)
-     */
-    ID         *id      __SELECTEDWHEN("type" == I3_OPT_TRIGGER_NOT_PRESENT ||\
-                                      "type" == I3_OPT_TRIGGER_RATELIMIT);
-    
-    /* the cache request is for the first ID in the stack 
-     * (type = I3_OPT_REQUEST_FOR_CACHE, I3_OPT_REQUEST_FOR_CACHE_SHORTCUT)
-     */ 
-    void       *nothing  __SELECTEDWHEN("type" == I3_OPT_REQUEST_FOR_CACHE || \
-                            "type" == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT || \
-                           "type" == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR);
-  } entry;
-  struct i3_option *next;
-} i3_option;
-        
-
-/*********************************
- ** structure of i3 option list **
- *********************************/
-        
-typedef struct i3_option_list
-{
-  i3_option *head;
-  i3_option *tail;
-} i3_option_list;
-
-
-/****************************
- ** structure of i3-header **
- ****************************/
-
-typedef struct i3_header
-{
-  uint8_t  ver;                /* version */
-  uint8_t  flags; 
-  struct i3_stack *stack;       /* stack of IDs */
-  i3_option_list  *option_list; /* option list */
-} i3_header;
-
-#define get_hdr_options(p) (p + ID_LEN*((p)[2] & 0xf) + 3*sizeof(char))
-#define get_hdr_stack(p) ((p) + 3*sizeof(char))
-#define get_flags(p) ((p)[1])
-#define get_stack_len(p) ( (p)[2] & 0xf)
-#define get_first_hop(p) ( get_flags(p) & I3_FIRST_HOP )
-#define set_first_hop(p) ( (p)[1] = (p)[1] | I3_FIRST_HOP )
-#define clear_first_hop(p) ( (p)[1] = (p)[1] & (~I3_FIRST_HOP) )
-
-
-/*****************************************************************
- * 
- * i3_header:
- *
- *  7              0               
- *  ----------------
- * | version        |   
- *  ----------------
- * | flags          |
- *  ----------------
- * | stacklen       |   
- *  ----------------
- * |                |                
- * |    i3_stack    |
- * |   (var size)   |
- * |     ...        |               
- *  ----------------
- * | option_list_len|   
- * |                |   
- *  ----------------
- * |                |
- * | i3_option_list |
- * |   (var size)   |
- * |     ...        |                
- *  ----------------
- * 
- * 
- *    i3_stack: list of i3 IDs (number of IDs < 16)
- *    ----------------
- *   |    ID #1       |
- *   |                |                
- *    ----------------
- *   |      ...       |                
- *   |                |
- *    ----------------
- *   |     ID #n      |
- *   |                |                
- *    ----------------
- *
- *    i3_option_list: list of i3_option's
- *    ----------------
- *   |  option list   |
- *   |     size       |
- *   |  (in bytes)    |
- *   |                |                
- *    ----------------
- *   |   i3 option    |
- *   |   (var size)   |
- *   |                |                
- *    ----------------
- *   |                |                
- *   |      ...       |                
- *   |                |
- *    ----------------
- *   |   i3 option    |
- *   |   (var size)   |
- *   |                |                
- *    ----------------
- *
- *   i3 options:
- *
- *      return address
- *      ---------------
- *     | opt type      |
- *      ---------------
- *     | data type     |
- *      ---------------                 
- *     | i3 stack or   |
- *     | IPv4 addr or  |
- *     | IPv6 add      |
- *      ----------------
- *      
- *      trigger
- *      ---------------
- *     | opt type      |
- *      ---------------
- *     | flags         |                
- *      ---------------                 
- *     |               |
- *     | i3 id (32B)   |
- *     |    ...        |
- *      ---------------
- *     |prefix len (2B)|
- *      ---------------
- *     |               |
- *     | Nonce (16B)   |
- *     |    ...        |
- *      ---------------
- *     | i3 address    |
- *      ---------------
- *
- *         i3_addr
- *        ---------------
- *       |   type        |
- *        ---------------
- *       | IPv4 addr or  |
- *       | IPv6 addr or  |
- *       | i3_stack      |
- *       ----------------
- *
- *         IPv4 addr
- *          ---------------                 
- *         |               |
- *         |   IP address  |
- *         |               |
- *         |               |
- *          ---------------
- *         |   port #      |
- *         |               |
- *          ---------------
- *
- *         IPv6 addr
- *          ---------------                 
- *         |               |
- *         |   IPv6 addr   |
- *         |    (16 B)     |
- *         |     ...       |
- *          ---------------
- *         |   port #      |
- *         |               |
- *          ---------------
- *
- *         I3 id
- *          ---------------                 
- *         |               |
- *         |               |
- *         |    (32 B)     |
- *         |     ...       |
- *          ---------------
- *
- *****************************************************************/
-
-
-#endif /* I3_H */
+/***************************************************************************
+*                         i3.h  -  description
+*                            -------------------
+*   begin                : Son Nov 17 2002
+*   email                : wehrle@xxxxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef I3_H
+#define I3_H
+
+#include <sys/types.h>
+#ifdef _WIN32
+    #include "../utils/fwint.h"
+#endif
+#include "../utils/netwrap.h"
+#ifdef __APPLE__
+#include <inttypes.h>  // Need uint8_t
+#include <sys/time.h>  // Need timeval
+#endif
+#include <assert.h>
+
+/* CLIENT_API_DEPRECIATED specifies whether the old client api is used */
+//#define  CLIENT_API_DEPRECIATED
+
+#ifndef TRUE
+#define TRUE  1
+#define FALSE 0
+#endif
+
+#define CHAR_BITS 8
+
+// first byte in a packet sent to an i3 server
+//   - normal i3 packet --> version number
+//   - i3 ping packet --> I3_PING_PACKET
+
+// note that i3 ping packets are not i3 packets; ping responses
+// should be from a different process, but for fatesharing reasons
+// implemented together
+#define I3_v01          0x10
+#define I3_PING_PKT     0x01
+
+#define I3_DATA         0x10
+#define I3_OPTION_LIST  0x20
+#define I3_FIRST_HOP    0x40
+
+#define I3_ADDR_TYPE_STACK 0x10
+#define I3_ADDR_TYPE_IPv4  0x20
+#define I3_ADDR_TYPE_IPv6  0x30
+#define I3_ADDR_TYPE_IPv4_NAT 0x40
+
+#define I3_ID_TYPE_PUBLIC       0x10
+#define I3_ID_TYPE_PRIVATE      0x20
+//#define I3_ID_TYPE_UNCONSTRAINED 0x30
+#define I3_ID_TYPE_UNKNOWN      0x40
+
+#define I3_OPT_SENDER                   0x01
+#define I3_OPT_TRIGGER_INSERT           0x02
+#define I3_OPT_TRIGGER_CHALLENGE        0x03
+#define I3_OPT_TRIGGER_ACK              0x04
+#define I3_OPT_TRIGGER_REMOVE           0x05
+#define I3_OPT_TRIGGER_NOT_PRESENT      0x06
+#define I3_OPT_REQUEST_FOR_CACHE        0x07
+#define I3_OPT_CACHE_ADDR               0x08
+#define I3_OPT_FORCE_CACHE_ADDR         0x09
+#define I3_OPT_CONSTRAINT_FAILED        0x10
+#define I3_OPT_ROUTE_BROKEN             0x11
+#define I3_OPT_REQUEST_FOR_CACHE_SHORTCUT 0x12
+#define I3_OPT_CACHE_SHORTCUT_ADDR      0x13
+#define I3_OPT_CACHE_DEST_ADDR          0x14
+#define I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR 0x15
+#define I3_OPT_DESTINATION              0x20
+#define I3_OPT_TRIGGER_RATELIMIT        0x30
+
+/* flags associated to trigger */
+#define I3_TRIGGER_FLAG_ALLOW_SHORTCUT  0x1
+#define I3_TRIGGER_FLAG_RATE_LIMIT      0x2
+
+#define I3_ERR_INVALID_VER       -1
+#define I3_ERR_INVALID_FLAGS     -2
+#define I3_ERR_PKT_LEN_TOO_SHORT -3
+#define I3_ERR_INVALID_STACK     -4
+#define I3_ERR_INVALID_ADDR      -5
+#define I3_ERR_INVALID_OPTLIST   -6
+#define I3_ERR_INVALID_OPTION    -7
+
+#define L_CONSTRAINT 0
+#define R_CONSTRAINT 1
+
+#define NEWS_INSTRUMENT 1
+
+#if NEWS_INSTRUMENT
+// 2 options for instrumenting i3 servers
+// maybe modified later for cleanliness
+#define I3_OPT_LOG_PACKET               0x0A
+#define I3_OPT_APPEND_TS                0x0B
+#define MAX_NEWS_OPTS                   2
+#endif
+
+#define OK              1
+#define ERROR           0
+
+#define INDENT_CONST    2       /* just for printing data nice for debugging */
+#define INDENT_BUF_LEN  100     /* just for printing data nice for debugging */
+
+
+/******************************
+** Type of an i3-id         **
+******************************/
+
+#define ID_LEN          32  /* in bytes */
+#define ID_LEN_BITS     256 /* in bits, i.e., ID_LEN_BITS = ID_LEN*8 */
+#define MIN_PREFIX_LEN  192 /* minimum prefix length that has to match */
+
+#define PREFIX_LEN      8
+#define KEY_LEN         16  /* length of key in bytes */
+
+#define PREFIX_ID(id)   (id.x)
+#define KEY_ID(id)      (id.x + PREFIX_LEN)
+#define KEY_ID_PTR(id)  (id->x + PREFIX_LEN)
+#define SUFFIX_ID(id)   (id.x + SUFFIX_LEN)
+typedef struct {
+    uint8_t x[ID_LEN];
+} ID;
+
+typedef struct {
+    uint8_t x[KEY_LEN];
+} Key;
+
+/******************************
+** structure of an i3-stack **
+******************************/
+
+#define I3_MAX_STACK_LEN 15
+typedef struct i3_stack {
+    int len; /* # of IDs in the stack */
+    ID *ids;
+} i3_stack;
+
+
+/********************************
+** structure of an i3 address **
+********************************/
+#ifndef CCURED
+ #define __SELECTEDWHEN(x)
+ #define __SELECTOR(x)
+ #define __RTTI
+#endif
+typedef struct i3_addr {
+    char type;
+    union {
+        /* I3_ADDR_TYPE_STACK */
+        i3_stack *stack __SELECTEDWHEN("type" == I3_ADDR_TYPE_STACK);
+
+        struct        /* I3_ADDR_TYPE_IPv4 */
+        {
+            struct in_addr addr;
+            uint16_t       port;
+        } v4 __SELECTEDWHEN("type" == I3_ADDR_TYPE_IPv4);
+
+        /* v4_nat is used to store all the information required to support
+         * NAT hosts:
+         *  - (host_addr, host_port) is the address of the host, which
+         *    can be behind NAT
+         *  - (nat_addr, nat_port) is the address assigned by the NAT to the 
host
+         *  - (i3srv_addr, i3srv_port) is the address of the first i3 server
+         *    to which the host sends packets
+         */
+        struct {
+            struct in_addr host_addr;
+            uint16_t       host_port;
+            struct in_addr nat_addr;
+            uint16_t       nat_port;
+            struct in_addr i3srv_addr;
+            uint16_t       i3srv_port;
+        } v4_nat __SELECTEDWHEN("type" == I3_ADDR_TYPE_IPv4_NAT);
+
+
+#ifndef __CYGWIN__
+        struct        /* I3_ADDR_TYPE_IPv6 */
+        {
+            struct in6_addr addr;
+            uint16_t        port;
+        } v6 __SELECTEDWHEN("type" == I3_ADDR_TYPE_IPv6);
+#endif
+    } t;
+} i3_addr;
+
+
+typedef struct token_bucket {
+#define TOKEN_BUCKET_PACKET 0
+#define TOKEN_BUCKET_BYTE   1
+    char     type; /* specifies whether units are "packets" or "bytes" */
+    uint32_t depth; /* token depth (bytes or packets) */
+    uint32_t r; /* long term rate (Bps or pps) */
+    uint32_t R; /* maximum rate (Bps or pps) */
+    /* only the first three fields are packed in packet;
+     * the following two fields are temporar variables
+     * used to implement the token bucket functionality
+     */
+    uint32_t tokens; /* actual number of tokens in the bucket (bytes or 
packets)
+                      * Note: "tokens" is never larger than "depth"
+                      */
+    uint64_t last_time; /* time since the previous packet has been
+                         * received (usec)
+                         */
+} token_bucket;
+
+#define NONCE_LEN  16
+typedef struct i3_trigger {
+    ID            id;
+    uint8_t       flags; /* possible flags:I3_TRIGGER_FLAG_ALLOW_SHORTCUT (0x1)
+                          * I3_TRIGGER_FLAG_RATE_LIMIT (0x2)
+                          */
+    uint16_t      prefix_len; /* packet ID should match trigID in the first
+                               * max(prefix_len, MIN_PREFIX_LEN) bits or more 
*/
+    char          nonce[NONCE_LEN];
+    i3_addr *     to;
+    Key           key;
+    token_bucket *tb; /* this is set only if I3_TRIGGER_FLAG_RATE_LIMIT is 
set*/
+} i3_trigger;
+
+
+/************************************
+** i3_option_entry data structure **
+************************************/
+
+typedef struct i3_option {
+    char type;
+    union {
+        /* sender address where to send a reply (type = I3_OPT_SENDER)
+         */
+        i3_addr   *ret_addr __SELECTEDWHEN("type" == I3_OPT_SENDER);
+
+        /* sender address where to send a reply (type = I3_OPT_SENDER)
+         */
+        i3_addr   *dst_addr __SELECTEDWHEN("type" == I3_OPT_DESTINATION);
+
+        /* trigger insertion and challenge
+         * (type = I3_OPT_TRIGGER_INSERT, I3_OPT_TRIGGER_CHALLENGE,
+         * I3_OPT_TRIGGER_ACK, I3_OPT_TRIGGER_REMOVE,
+         * I3_OPT_CACHE_ADDR, I3_OPT_CACHE_SHORTCUT_ADDR,
+         * I3_OPT_CACHE_DEST_ADDR,
+         * I3_OPT_CONSTRAINT_FAILED, I3_OPT_ROUTE_BROKEN)
+         *
+         * When I3_OPT_CACHE_ADDR is used, trigger->to represents the
+         * the address suggested by the i3 server (e.g., its own address)
+         * where client should send data and control messages addressed to
+         * any identifier that shares MIN_PREFIX_LEN bits with trigger->id.
+         * Thus, this option allows the client to cache the address of a server
+         * responsible for a certain identifier.
+         * When I3_OPT_CACHE_SHORTCUT_ADDR is used, trigger->to represents the
+         * the address of the end host. This option is sent directly to the
+         * receiver. The receiver can see whether the sender is behind a NAT
+         * by comparing the IP source address of the packet and the IP address
+         * in trigger->to.
+         */
+        i3_trigger *trigger __SELECTEDWHEN("type" == I3_OPT_TRIGGER_INSERT || \
+                                           "type" == I3_OPT_TRIGGER_CHALLENGE 
|| \
+                                           "type" == I3_OPT_TRIGGER_ACK || \
+                                           "type" == I3_OPT_TRIGGER_REMOVE || \
+                                           "type" == I3_OPT_CACHE_ADDR || \
+                                           "type" == I3_OPT_CACHE_DEST_ADDR || 
\
+                                           "type" == 
I3_OPT_CACHE_SHORTCUT_ADDR || \
+                                           "type" == I3_OPT_CONSTRAINT_FAILED \
+                                           "type" == I3_OPT_ROUTE_BROKEN);
+
+        /* id to which the reply refers to (type = I3_OPT_TRIGGER_NOT_PRESENT,
+         * I3_OPT_REQUEST_FOR_CACHE, I3_OPT_TRIGGER_RATELIMIT)
+         */
+        ID         *id __SELECTEDWHEN("type" == I3_OPT_TRIGGER_NOT_PRESENT || \
+                                      "type" == I3_OPT_TRIGGER_RATELIMIT);
+
+        /* the cache request is for the first ID in the stack
+         * (type = I3_OPT_REQUEST_FOR_CACHE, I3_OPT_REQUEST_FOR_CACHE_SHORTCUT)
+         */
+        void       *nothing __SELECTEDWHEN("type" == I3_OPT_REQUEST_FOR_CACHE 
|| \
+                                           "type" == 
I3_OPT_REQUEST_FOR_CACHE_SHORTCUT || \
+                                           "type" == 
I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR);
+    } entry;
+    struct i3_option *next;
+} i3_option;
+
+
+/*********************************
+** structure of i3 option list **
+*********************************/
+
+typedef struct i3_option_list {
+    i3_option *head;
+    i3_option *tail;
+} i3_option_list;
+
+
+/****************************
+** structure of i3-header **
+****************************/
+
+typedef struct i3_header {
+    uint8_t          ver;       /* version */
+    uint8_t          flags;
+    struct i3_stack *stack;     /* stack of IDs */
+    i3_option_list * option_list; /* option list */
+} i3_header;
+
+#define get_hdr_options(p) (p + ID_LEN * ((p)[2] & 0xf) + 3 * sizeof(char))
+#define get_hdr_stack(p) ((p) + 3 * sizeof(char))
+#define get_flags(p) ((p)[1])
+#define get_stack_len(p) ((p)[2] & 0xf)
+#define get_first_hop(p) (get_flags(p) & I3_FIRST_HOP)
+#define set_first_hop(p) ((p)[1] = (p)[1] | I3_FIRST_HOP)
+#define clear_first_hop(p) ((p)[1] = (p)[1] & (~I3_FIRST_HOP))
+
+
+/*****************************************************************
+*
+* i3_header:
+*
+*  7              0
+*  ----------------
+* | version        |
+*  ----------------
+* | flags          |
+*  ----------------
+* | stacklen       |
+*  ----------------
+* |                |
+* |    i3_stack    |
+* |   (var size)   |
+* |     ...        |
+*  ----------------
+* | option_list_len|
+* |                |
+*  ----------------
+* |                |
+* | i3_option_list |
+* |   (var size)   |
+* |     ...        |
+*  ----------------
+*
+*
+*    i3_stack: list of i3 IDs (number of IDs < 16)
+*    ----------------
+*   |    ID #1       |
+*   |                |
+*    ----------------
+*   |      ...       |
+*   |                |
+*    ----------------
+*   |     ID #n      |
+*   |                |
+*    ----------------
+*
+*    i3_option_list: list of i3_option's
+*    ----------------
+*   |  option list   |
+*   |     size       |
+*   |  (in bytes)    |
+*   |                |
+*    ----------------
+*   |   i3 option    |
+*   |   (var size)   |
+*   |                |
+*    ----------------
+*   |                |
+*   |      ...       |
+*   |                |
+*    ----------------
+*   |   i3 option    |
+*   |   (var size)   |
+*   |                |
+*    ----------------
+*
+*   i3 options:
+*
+*      return address
+*      ---------------
+*     | opt type      |
+*      ---------------
+*     | data type     |
+*      ---------------
+*     | i3 stack or   |
+*     | IPv4 addr or  |
+*     | IPv6 add      |
+*      ----------------
+*
+*      trigger
+*      ---------------
+*     | opt type      |
+*      ---------------
+*     | flags         |
+*      ---------------
+*     |               |
+*     | i3 id (32B)   |
+*     |    ...        |
+*      ---------------
+*     |prefix len (2B)|
+*      ---------------
+*     |               |
+*     | Nonce (16B)   |
+*     |    ...        |
+*      ---------------
+*     | i3 address    |
+*      ---------------
+*
+*         i3_addr
+*        ---------------
+*       |   type        |
+*        ---------------
+*       | IPv4 addr or  |
+*       | IPv6 addr or  |
+*       | i3_stack      |
+*       ----------------
+*
+*         IPv4 addr
+*          ---------------
+*         |               |
+*         |   IP address  |
+*         |               |
+*         |               |
+*          ---------------
+*         |   port #      |
+*         |               |
+*          ---------------
+*
+*         IPv6 addr
+*          ---------------
+*         |               |
+*         |   IPv6 addr   |
+*         |    (16 B)     |
+*         |     ...       |
+*          ---------------
+*         |   port #      |
+*         |               |
+*          ---------------
+*
+*         I3 id
+*          ---------------
+*         |               |
+*         |               |
+*         |    (32 B)     |
+*         |     ...       |
+*          ---------------
+*
+*****************************************************************/
+
+
+#endif /* I3_H */

=== modified file 'i3/i3/i3_addr.c'
--- i3/i3/i3_addr.c     2010-01-06 17:03:26 +0000
+++ i3/i3/i3_addr.c     2010-02-11 11:49:47 +0000
@@ -1,677 +1,683 @@
-/***************************************************************************
-                          i3_addr.c  -  description
-                             -------------------
-    begin                : Nov 18 2002
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#include "i3.h"
-#include "i3_fun.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifndef _WIN32 
-#      include <sys/types.h>
-#      include <sys/socket.h>
-#      include <netinet/in.h>
-#      include <arpa/inet.h>
-#endif
-
-#include "i3_debug.h"
-
-
-#include "../utils/gen_utils.h"
-
-/***************************************************************************
- *  alloc_i3_addr - allocate address data structure
- *
- *  return:
- *    pointer to the allocated data structure 
- ***************************************************************************/
-i3_addr *alloc_i3_addr()
-{
-  i3_addr *addr;
-
-  /* TODO: just simply call alloc for now;
-   * preallocate a pool of buffers in the future */
-  addr = (i3_addr *)malloc(sizeof(i3_addr));
-  if (addr) 
-    return addr;
-
-  I3_PRINT_INFO0(
-          I3_INFO_LEVEL_FATAL_ERROR, 
-          "FATAL ERROR: memory allocation error in alloc_i3_addr\n"
-        );
-  return NULL;
-}
-
-
-/***************************************************************************
- *  init_i3_addr_ipv4, init_i3_addr_ipv6, init_i3_addr_stack - 
- *    initailize the fields of address data structure
- *
- *  input:
- *    addr, port: IPv4/IPv6 address and port numbres
- *    - or -
- *    stack: pointer to stack (this data structure is not copied; don't
- *           free it after calling the function)
- *
- ***************************************************************************/
-void init_i3_addr_ipv4(i3_addr *a, struct in_addr addr, uint16_t port)
-{
-  a->type = I3_ADDR_TYPE_IPv4;
-  a->t.v4.addr.s_addr = addr.s_addr;
-  a->t.v4.port = port;
-}
-
-void init_i3_addr_ipv4_nat(i3_addr *a, 
-                          struct in_addr host_addr, uint16_t host_port,
-                          struct in_addr nat_addr, uint16_t nat_port,
-                          struct in_addr i3srv_addr, uint16_t i3srv_port)
-{
-  a->type = I3_ADDR_TYPE_IPv4_NAT;
-  a->t.v4_nat.host_addr.s_addr = host_addr.s_addr;
-  a->t.v4_nat.host_port = host_port;
-  a->t.v4_nat.nat_addr.s_addr = nat_addr.s_addr;
-  a->t.v4_nat.nat_port = nat_port;
-  a->t.v4_nat.i3srv_addr.s_addr = i3srv_addr.s_addr;
-  a->t.v4_nat.i3srv_port = i3srv_port;
-}
-#ifndef __CYGWIN__
-void init_i3_addr_ipv6(i3_addr *a, struct in6_addr addr, uint16_t port)
-{
-  a->type = I3_ADDR_TYPE_IPv6;
-#ifndef CCURED  
-  memcpy((char *)&a->t.v6.addr.s6_addr, (char *)&addr.s6_addr,
-        sizeof(struct in6_addr));
-#else
-  a->t.v6.addr = addr;
-#endif  
-  a->t.v6.port = port;
-}
-#endif
-void init_i3_addr_stack(i3_addr *a, i3_stack *s)
-{
-  a->type = I3_ADDR_TYPE_STACK;
-  a->t.stack = s;
-}
-
-
-/***************************************************************************
- *  free_i3_trigger - free address data structure
- *
- *  input:
- *    i3 address to be freed
- *
- ***************************************************************************/
-
-void free_i3_addr(i3_addr *addr)
-{
-  if (addr->type == I3_ADDR_TYPE_STACK)
-    free_i3_stack(addr->t.stack);
-  free(addr);
-}
-
-/***************************************************************************
- *  duplicate_i3_addr - duplicate a given address
- *
- *  input:
- *    a - address to be duplicated
- *
- *  return:
- *    a's replica
- ***************************************************************************/
-
-i3_addr *duplicate_i3_addr(i3_addr *a)
-{
-  i3_addr *anew;
-
-  if (NULL == a)
-    return NULL;
-  else
-    anew = alloc_i3_addr();
-
-  anew->type = a->type;
-  switch (a->type) {
-  case I3_ADDR_TYPE_IPv4:
-    anew->t.v4.addr.s_addr = a->t.v4.addr.s_addr;
-    anew->t.v4.port = a->t.v4.port;
-    break;
-  case I3_ADDR_TYPE_IPv4_NAT:
-    anew->t.v4_nat.host_addr.s_addr = a->t.v4_nat.host_addr.s_addr;
-    anew->t.v4_nat.host_port = a->t.v4_nat.host_port;
-    anew->t.v4_nat.nat_addr.s_addr = a->t.v4_nat.nat_addr.s_addr;
-    anew->t.v4_nat.nat_port = a->t.v4_nat.nat_port;
-    anew->t.v4_nat.i3srv_addr.s_addr = a->t.v4_nat.i3srv_addr.s_addr;
-    anew->t.v4_nat.i3srv_port = a->t.v4_nat.i3srv_port;
-    break;
-#ifndef __CYGWIN__
-  case I3_ADDR_TYPE_IPv6:
-#ifndef CCURED    
-    memcpy((char *)&anew->t.v6.addr.s6_addr, (char *)&a->t.v6.addr.s6_addr,
-         sizeof(struct in6_addr));
-#else
-    // Cleaner and faster
-    anew->t.v6.addr = a->t.v6.addr;
-#endif    
-    anew->t.v6.port = a->t.v6.port;
-    break;
-#endif
-  case I3_ADDR_TYPE_STACK:
-    anew->t.stack = duplicate_i3_stack(a->t.stack);
-    break;
-  default:
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "duplicate_i3_id: invalid address 
type %d.\n", a->type);
-  }
-
-  return anew;
-}
-
-
-
-/***************************************************************************
- *  pack_i3_addr - convert an i3 address data structure in packet format
- *
- *  input:
- *    p - address of the buffer where the address is to be stored in 
- *        packet format (pre-allocated)
- *    addr - trigger to be converted in packet format
- *    
- *  output:
- *    length - length of the address in packet format
- *
- ***************************************************************************/
-
-void pack_i3_addr(char *p, i3_addr *addr, unsigned short *length)
-{
-  unsigned short len = 0, l;
-  long         long_temp;
-  short        short_temp; 
-
-  p[0] = addr->type;
-  p++; len++;
-
-  switch (addr->type) {
-    case I3_ADDR_TYPE_STACK:
-      pack_i3_stack(p, addr->t.stack, &l);
-      len += l;
-      break;
-      
-    case I3_ADDR_TYPE_IPv4:
-      long_temp = htonl(addr->t.v4.addr.s_addr);
-      memcpy(p, (char *)&long_temp, sizeof(long));
-      p += sizeof(long);
-      len += sizeof(long);
-      
-      short_temp = htons(addr->t.v4.port);
-      memcpy(p, &short_temp, sizeof(short));
-      p += sizeof(short);
-      len += sizeof(short);
-      
-      break;
-      
-    case I3_ADDR_TYPE_IPv4_NAT:
-      long_temp = htonl(addr->t.v4_nat.host_addr.s_addr);
-      memcpy(p, (char *)&long_temp, sizeof(long));
-      p += sizeof(long);
-      len += sizeof(long);
-      short_temp = htons(addr->t.v4_nat.host_port);
-      memcpy(p, &short_temp, sizeof(short));
-      p += sizeof(short);
-      len += sizeof(short);
-      
-      long_temp = htonl(addr->t.v4_nat.nat_addr.s_addr);
-      memcpy(p, (char *)&long_temp, sizeof(long));
-      p += sizeof(long);
-      len += sizeof(long);
-      short_temp = htons(addr->t.v4_nat.nat_port);
-      memcpy(p, &short_temp, sizeof(short));
-      p += sizeof(short);
-      len += sizeof(short);
-      
-      long_temp = htonl(addr->t.v4_nat.i3srv_addr.s_addr);
-      memcpy(p, (char *)&long_temp, sizeof(long));
-      p += sizeof(long);
-      len += sizeof(long);
-      short_temp = htons(addr->t.v4_nat.i3srv_port);
-      memcpy(p, &short_temp, sizeof(short));
-      p += sizeof(short);
-      len += sizeof(short);
-      break;
-      
-#ifndef _WIN32
-    case I3_ADDR_TYPE_IPv6:
-#ifndef CCURED      
-      memcpy(p, (char *)&addr->t.v6.addr.s6_addr, sizeof(struct in6_addr));
-#else
-      * (struct in6_addr *)p = addr->t.v6.addr;
-#endif      
-      p += sizeof(struct in6_addr);
-      len += sizeof(struct in6_addr);
-      
-      short_temp = htons(addr->t.v6.port);
-      memcpy(p, &short_temp, sizeof(short));
-      len += sizeof(short);
-      p += sizeof(short);
-      
-      break;
-#endif    
-      
-    default:
-      printf("pack_i3_addr: invalid address type %d\n", addr->type);
-  }
-
-  *length = len;
-}
-
-unsigned short get_i3_addr_len(i3_addr *addr)
-{
-  unsigned short length;
-
-  length = sizeof(char); /* type */
-
-  switch (addr->type) {
-  case I3_ADDR_TYPE_STACK:
-    length += get_i3_stack_len(addr->t.stack);
-    break;
-  case I3_ADDR_TYPE_IPv4:
-    length += sizeof(long) + sizeof(short);
-    break;
-  case I3_ADDR_TYPE_IPv4_NAT:
-    length += 3*(sizeof(long) + sizeof(short));
-    break;
-#ifndef __CYGWIN__  
-  case I3_ADDR_TYPE_IPv6:
-    length += sizeof(struct in6_addr) + sizeof(short);
-    break;
-#endif
-  default:
-         I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "pack_i3_addr: invalid 
address type %d\n", addr->type);
-  }
-
-  return length;
-}
-
-
-/***************************************************************************
- *  unpack_i3_addr - copy address info from packet to a trigger 
- *                   data structure 
- *
- *  input:
- *    p - address where address is stored in packet format
- *    
- *  return:
- *    address data structure initialized with the info from buffer "p"
- *
- *  output:
- *    length - length of the address info in packet format
- *
- ***************************************************************************/
-
-i3_addr *unpack_i3_addr(char *p, unsigned short *length)
-{
-  unsigned short len;
-  i3_addr *addr = alloc_i3_addr();
-
-  addr->type = p[0];
-  p++; *length = 1;
-
-  switch (addr->type) {
-    case I3_ADDR_TYPE_STACK:
-      addr->t.stack = unpack_i3_stack(p, &len);
-      *length += len;
-      break;
-      
-    case I3_ADDR_TYPE_IPv4:
-      addr->t.v4.addr.s_addr = ntohl(*((long *)p));
-      p += sizeof(long);
-      *length += sizeof(long);
-      
-      addr->t.v4.port = ntohs(*((short *)p));
-      *length += sizeof(short);
-      p += sizeof(short);
-      
-      break;
-    
-    case I3_ADDR_TYPE_IPv4_NAT:
-      addr->t.v4_nat.host_addr.s_addr = ntohl(*((long *)p));
-      p += sizeof(long);
-      *length += sizeof(long);
-      addr->t.v4_nat.host_port = ntohs(*((short *)p));
-      *length += sizeof(short);
-      p += sizeof(short);
-      
-      addr->t.v4_nat.nat_addr.s_addr = ntohl(*((long *)p));
-      p += sizeof(long);
-      *length += sizeof(long);
-      addr->t.v4_nat.nat_port = ntohs(*((short *)p));
-      *length += sizeof(short);
-      p += sizeof(short);
-      
-      addr->t.v4_nat.i3srv_addr.s_addr = ntohl(*((long *)p));
-      p += sizeof(long);
-      *length += sizeof(long);
-      addr->t.v4_nat.i3srv_port = ntohs(*((short *)p));
-      *length += sizeof(short);
-      p += sizeof(short);
-      break;
-    
-#ifndef __CYGWIN__
-    case I3_ADDR_TYPE_IPv6:
-#ifndef CCURED      
-      memcpy((char *)&addr->t.v6.addr.s6_addr, p, sizeof(struct in6_addr));
-#else
-      addr->t.v6.addr = * (struct in6_addr *)p;
-#endif
-      
-      p += sizeof(struct in6_addr);
-      *length += sizeof(struct in6_addr);
-      
-      addr->t.v6.port = ntohs(*((short *)p));
-      *length += sizeof(short);
-      p += sizeof(short);
-      
-      break;
-#endif
-
-    default:
-      I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL,"unpack_i3_addr: invalid address 
type %d\n", addr->type);
-  }
-  return addr;
-}
-
-/***************************************************************************
- *  check_i3_addr - check address whether is well-formed
- *
- *  input:
- *    p - address where i3_addr is stored in packet format
- *    
- *  return:
- *    error code; FALSE if no error
- *
- *  output:
- *    length - length of the address info in packet format
- *
- ***************************************************************************/
-
-int check_i3_addr(char *p, unsigned short *length, char *type)
-{
-  *type = p[0];
-
-  p++; /* skip address type field */
-
-  switch (*type) {
-    case I3_ADDR_TYPE_STACK:
-      check_i3_stack(p, length); 
-      break;
-    case I3_ADDR_TYPE_IPv4:
-      *length = sizeof(long)/*IP address*/ + sizeof(short)/*port*/;
-      break;
-    case I3_ADDR_TYPE_IPv4_NAT:
-      *length = 3*(sizeof(long)/*IP address*/ + sizeof(short)/*port*/);
-      break;
-#ifndef __CYGWIN__
-    case I3_ADDR_TYPE_IPv6:
-      *length = sizeof(struct in6_addr)/*IP address*/ + sizeof(short)/*port*/;
-      break;
-#endif
-    default:
-      return I3_ERR_INVALID_ADDR;
-
-  }
-
-  *length += 1; /* account for address type */
-
-  return FALSE;
-}
-
-
-/**
-  * This function understands natted addresses.
-  * If an address is natted, the nat_address and nat_port number
-  * are used in the comparison.
-  * @author Dilip
-  */
-int addr_nat_equal(i3_addr *a1, i3_addr *a2)
-{
- 
-  struct in_addr cmp_addr_A, cmp_addr_B;
-  int cmp_port_A = 0, cmp_port_B = 0;
- 
-  memset(&cmp_addr_A, 0, sizeof(struct in_addr));
-  memset(&cmp_addr_B, 0, sizeof(struct in_addr));
- 
-  if (a1->type == I3_ADDR_TYPE_IPv4) {
-    memcpy(&cmp_addr_A, &a1->t.v4.addr, sizeof(struct in_addr));
-    cmp_port_A = a1->t.v4.port;
-  } else if (a1->type == I3_ADDR_TYPE_IPv4_NAT) {
-    memcpy(&cmp_addr_A, &a1->t.v4_nat.host_addr, sizeof(struct in_addr));
-    cmp_port_A = a1->t.v4_nat.host_port;
-  }
-
-  if (a2->type == I3_ADDR_TYPE_IPv4) {
-    memcpy(&cmp_addr_B, &a2->t.v4.addr, sizeof(struct in_addr));
-    cmp_port_B = a2->t.v4.port;
-  } else if (a2->type == I3_ADDR_TYPE_IPv4_NAT) {
-    memcpy(&cmp_addr_B, &a2->t.v4_nat.host_addr, sizeof(struct in_addr));
-    cmp_port_B = a2->t.v4_nat.host_port;
-  }
-
-    if (cmp_addr_A.s_addr != cmp_addr_B.s_addr || cmp_port_A != cmp_port_B) {
-        return FALSE;
-    } else {
-        return TRUE;
-    }
-  
-}
-
-
-/***************************************************************************
- *  addr_equal - compare two addresses
- *
- *  input:
- *    t1, t2 - addresses to be compared
- *    
- *  return:
- *    TRUE, if the addresses are identical; FALSE, otherwise
- *
- ***************************************************************************/
-
-int addr_equal(i3_addr *a1, i3_addr *a2)
-{
-#ifndef __CYGWIN__
-  uint i;
-#endif
-
-  if (a1->type != a2->type)
-    return FALSE;
- 
-  switch (a1->type) {
-  case I3_ADDR_TYPE_IPv4:
-    if ((a1->t.v4.addr.s_addr != a2->t.v4.addr.s_addr) ||
-       (a1->t.v4.port != a2->t.v4.port))
-      return FALSE;
-    break;
-  case I3_ADDR_TYPE_IPv4_NAT:
-    if ((a1->t.v4_nat.host_addr.s_addr != a2->t.v4_nat.host_addr.s_addr) ||
-       (a1->t.v4_nat.host_port != a2->t.v4_nat.host_port) ||
-       (a1->t.v4_nat.nat_addr.s_addr != a2->t.v4_nat.nat_addr.s_addr) ||
-       (a1->t.v4_nat.nat_port != a2->t.v4_nat.nat_port) ||
-       (a1->t.v4_nat.i3srv_addr.s_addr != a2->t.v4_nat.i3srv_addr.s_addr) ||
-       (a1->t.v4_nat.i3srv_port != a2->t.v4_nat.i3srv_port))
-      return FALSE;
-    break;
-#ifndef __CYGWIN__
-  case I3_ADDR_TYPE_IPv6:
-    for (i = 0; i < sizeof(struct in6_addr); i++) 
-      if (a1->t.v6.addr.s6_addr[i] != a2->t.v6.addr.s6_addr[i])
-       return FALSE;
-    if (a1->t.v6.port == a2->t.v6.port)
-      return FALSE;
-    break;
-#endif
-  case I3_ADDR_TYPE_STACK:
-    if (a1->t.stack->len != a2->t.stack->len)
-      return FALSE;
-    if (memcmp((char *)a1->t.stack->ids, (char *)a2->t.stack->ids, 
-              a1->t.stack->len*sizeof(ID)))
-      return FALSE;
-  }
-  return TRUE;
-}
-
-
-/***************************************************************************
- *  sizeof_addr - return the length of the address data structure
- *
- *  input:
- *    a - given address
- *
- *  return:
- *    length in bytes of the address
- *
- ***************************************************************************/
-
-int sizeof_addr(i3_addr *a)
-{
-  switch (a->type) {
-  case I3_ADDR_TYPE_IPv4:
-    return (sizeof(struct in_addr) + sizeof(uint16_t) + sizeof(a->type) + 
-           KEY_LEN);
-  case I3_ADDR_TYPE_IPv4_NAT:
-    return (3*(sizeof(struct in_addr) + sizeof(uint16_t)) + sizeof(a->type) + 
-           KEY_LEN);
-#ifndef __CYGWIN__
-  case I3_ADDR_TYPE_IPv6:
-    return (sizeof(struct in6_addr) + sizeof(uint16_t) + sizeof(a->type) + 
-           KEY_LEN);
-#endif
-  case I3_ADDR_TYPE_STACK:
-    return (a->t.stack->len*sizeof(ID) + sizeof(a->type));
-  }
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "addr_len: Invalid trigger type");
-  return -1;
-}
-
-/***************************************************************************
- * printf_id - print i3-id with an indentation of "indent"
- **************************************************************************/
-
-void printf_id(ID *id, int indent)
-{
-  uint i;
-  char buf[INDENT_BUF_LEN];
-
-  memset(buf, ' ', indent);
-  buf[indent] = 0;
-
-  printf("%s i3-id = ", buf);
-  for (i = 0; i < sizeof(ID); i++)
-    printf("%02x", id->x[i]); 
-  printf("\n");
-}    
-   
-/***************************************************************************
- * printf_i3_addr - print i3-addr with an indentation of "indent"
- **************************************************************************/
-
-void printf_i3_addr(i3_addr *addr, int indent)
-{
-#ifndef __CYGWIN__
-  uint i;
-#endif
-  char buf[INDENT_BUF_LEN];
-  struct in_addr ia;
-
-  memset(buf, ' ', indent);
-  buf[indent] = 0;
-
-  printf("%s addr type = %d\n", buf, addr->type);
-
-  switch (addr->type) {
-  case I3_ADDR_TYPE_STACK:
-    printf_i3_stack(addr->t.stack, indent);
-    break;
-  case I3_ADDR_TYPE_IPv4:
-    ia.s_addr = htonl(addr->t.v4.addr.s_addr);
-    printf("%s IPv4 (address, port) = (%s, %d)", 
-          buf, inet_ntoa(ia), addr->t.v4.port); 
-    break;
-  case I3_ADDR_TYPE_IPv4_NAT:
-    ia.s_addr = htonl(addr->t.v4_nat.host_addr.s_addr);
-    printf("%s NAT_IPv4 (host_addr, host_port) = (%s, %d)\n", 
-          buf, inet_ntoa(ia), addr->t.v4_nat.host_port); 
-    ia.s_addr = htonl(addr->t.v4_nat.nat_addr.s_addr);
-    printf("%s          (nat_addr, nat_port) = (%s, %d)\n", 
-          buf, inet_ntoa(ia), addr->t.v4_nat.nat_port); 
-    ia.s_addr = htonl(addr->t.v4_nat.i3srv_addr.s_addr);
-    printf("%s          (i3srv_addr, i3srv_port) = (%s, %d)\n", 
-          buf, inet_ntoa(ia), addr->t.v4_nat.i3srv_port); 
-    break;
-#ifndef __CYGWIN__
-  case I3_ADDR_TYPE_IPv6:
-    printf("%s IPv6 (address, port) = (", buf);
-    for (i = 0; i < sizeof(struct in6_addr); i++) 
-      printf("%d.", addr->t.v6.addr.s6_addr[i]);
-    printf(", %d)", addr->t.v6.port);
-    break;
-#endif
-  default:
-    printf("Unknown addr type\n");
-  }
-  printf("\n");
-}
-
-/***************************************************************************
- * compute_nonce - compute the nonce for challenging trigger insertion
- **************************************************************************/
-
-void compute_nonce(char *nonce, i3_addr *a)
-{
-  memset(nonce, 0, NONCE_LEN);
-
-  switch (a->type) {
-  case I3_ADDR_TYPE_IPv4:
-#ifndef CCURED    
-    memcpy(nonce, (char *)&a->t.v4.addr.s_addr, sizeof(struct in_addr));
-#else
-    * (struct in_addr *)nonce = a->t.v4.addr;
-#endif
-#ifndef CCURED    
-    memcpy(nonce + sizeof(struct in_addr),
-         (char *)&a->t.v4.port, sizeof(a->t.v4.port));
-#else
-    * (uint16_t *)(nonce + sizeof(struct in_addr)) = a->t.v4.port;
-#endif    
-    break;
-  case I3_ADDR_TYPE_IPv4_NAT:
-    /* the 2nd address in the two-hop route represents the 
-     * the Internet-routable address of the destination
-     */
-    memcpy(nonce, (char *)&a->t.v4_nat.nat_addr.s_addr, 
-          sizeof(struct in_addr));
-    memcpy(nonce + sizeof(struct in_addr),
-          (char *)&a->t.v4_nat.host_port, sizeof(a->t.v4_nat.nat_port));
-    break;
-#ifndef __CYGWIN__
-  case I3_ADDR_TYPE_IPv6:
-#ifndef CCURED    
-    memcpy(nonce, (char *)&a->t.v6.addr.s6_addr,
-         MIN(sizeof(struct in6_addr), NONCE_LEN));
-#else
-    {
-      struct in6_addr tmp = a->t.v6.addr;
-      memcpy(nonce, (char*)&tmp, MIN(sizeof(struct in6_addr), NONCE_LEN));
-    }
-#endif    
-    break;
-#endif
-  case I3_ADDR_TYPE_STACK:
-    memcpy(nonce, a->t.stack->ids, NONCE_LEN);
-    break;
-  default:
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL,"compute_nonce: invalid address 
type %d\n", a->type);
-    printf_i3_addr(a, 2);
-  }
-}
+/***************************************************************************
+*                         i3_addr.c  -  description
+*                            -------------------
+*   begin                : Nov 18 2002
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#include "i3.h"
+#include "i3_fun.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifndef _WIN32
+#       include <sys/types.h>
+#       include <sys/socket.h>
+#       include <netinet/in.h>
+#       include <arpa/inet.h>
+#endif
+
+#include "i3_debug.h"
+
+
+#include "../utils/gen_utils.h"
+
+/***************************************************************************
+*  alloc_i3_addr - allocate address data structure
+*
+*  return:
+*    pointer to the allocated data structure
+***************************************************************************/
+i3_addr *alloc_i3_addr()
+{
+    i3_addr *addr;
+
+    /* TODO: just simply call alloc for now;
+     * preallocate a pool of buffers in the future */
+    addr = (i3_addr *) malloc(sizeof(i3_addr));
+    if (addr) {
+        return addr;
+    }
+
+    I3_PRINT_INFO0(
+        I3_INFO_LEVEL_FATAL_ERROR,
+        "FATAL ERROR: memory allocation error in alloc_i3_addr\n"
+        );
+    return NULL;
+}
+
+/***************************************************************************
+*  init_i3_addr_ipv4, init_i3_addr_ipv6, init_i3_addr_stack -
+*    initailize the fields of address data structure
+*
+*  input:
+*    addr, port: IPv4/IPv6 address and port numbres
+*    - or -
+*    stack: pointer to stack (this data structure is not copied; don't
+*           free it after calling the function)
+*
+***************************************************************************/
+void init_i3_addr_ipv4(i3_addr *a, struct in_addr addr, uint16_t port)
+{
+    a->type             = I3_ADDR_TYPE_IPv4;
+    a->t.v4.addr.s_addr = addr.s_addr;
+    a->t.v4.port        = port;
+}
+
+void init_i3_addr_ipv4_nat(i3_addr *a,
+                           struct in_addr host_addr, uint16_t host_port,
+                           struct in_addr nat_addr, uint16_t nat_port,
+                           struct in_addr i3srv_addr, uint16_t i3srv_port)
+{
+    a->type                       = I3_ADDR_TYPE_IPv4_NAT;
+    a->t.v4_nat.host_addr.s_addr  = host_addr.s_addr;
+    a->t.v4_nat.host_port         = host_port;
+    a->t.v4_nat.nat_addr.s_addr   = nat_addr.s_addr;
+    a->t.v4_nat.nat_port          = nat_port;
+    a->t.v4_nat.i3srv_addr.s_addr = i3srv_addr.s_addr;
+    a->t.v4_nat.i3srv_port        = i3srv_port;
+}
+
+#ifndef __CYGWIN__
+void init_i3_addr_ipv6(i3_addr *a, struct in6_addr addr, uint16_t port)
+{
+    a->type = I3_ADDR_TYPE_IPv6;
+#ifndef CCURED
+    memcpy((char *) &a->t.v6.addr.s6_addr, (char *) &addr.s6_addr,
+           sizeof(struct in6_addr));
+#else
+    a->t.v6.addr = addr;
+#endif
+    a->t.v6.port = port;
+}
+
+#endif
+void init_i3_addr_stack(i3_addr *a, i3_stack *s)
+{
+    a->type    = I3_ADDR_TYPE_STACK;
+    a->t.stack = s;
+}
+
+/***************************************************************************
+*  free_i3_trigger - free address data structure
+*
+*  input:
+*    i3 address to be freed
+*
+***************************************************************************/
+
+void free_i3_addr(i3_addr *addr)
+{
+    if (addr->type == I3_ADDR_TYPE_STACK) {
+        free_i3_stack(addr->t.stack);
+    }
+    free(addr);
+}
+
+/***************************************************************************
+*  duplicate_i3_addr - duplicate a given address
+*
+*  input:
+*    a - address to be duplicated
+*
+*  return:
+*    a's replica
+***************************************************************************/
+
+i3_addr *duplicate_i3_addr(i3_addr *a)
+{
+    i3_addr *anew;
+
+    if (NULL == a) {
+        return NULL;
+    } else {
+        anew = alloc_i3_addr();
+    }
+
+    anew->type = a->type;
+    switch (a->type) {
+    case I3_ADDR_TYPE_IPv4:
+        anew->t.v4.addr.s_addr           = a->t.v4.addr.s_addr;
+        anew->t.v4.port                  = a->t.v4.port;
+        break;
+    case I3_ADDR_TYPE_IPv4_NAT:
+        anew->t.v4_nat.host_addr.s_addr  = a->t.v4_nat.host_addr.s_addr;
+        anew->t.v4_nat.host_port         = a->t.v4_nat.host_port;
+        anew->t.v4_nat.nat_addr.s_addr   = a->t.v4_nat.nat_addr.s_addr;
+        anew->t.v4_nat.nat_port          = a->t.v4_nat.nat_port;
+        anew->t.v4_nat.i3srv_addr.s_addr = a->t.v4_nat.i3srv_addr.s_addr;
+        anew->t.v4_nat.i3srv_port        = a->t.v4_nat.i3srv_port;
+        break;
+#ifndef __CYGWIN__
+    case I3_ADDR_TYPE_IPv6:
+#ifndef CCURED
+        memcpy((char *) &anew->t.v6.addr.s6_addr, (char *) 
&a->t.v6.addr.s6_addr,
+               sizeof(struct in6_addr));
+#else
+        // Cleaner and faster
+        anew->t.v6.addr = a->t.v6.addr;
+#endif
+        anew->t.v6.port = a->t.v6.port;
+        break;
+#endif
+    case I3_ADDR_TYPE_STACK:
+        anew->t.stack   = duplicate_i3_stack(a->t.stack);
+        break;
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "duplicate_i3_id: invalid 
address type %d.\n", a->type);
+    }
+
+    return anew;
+}
+
+/***************************************************************************
+*  pack_i3_addr - convert an i3 address data structure in packet format
+*
+*  input:
+*    p - address of the buffer where the address is to be stored in
+*        packet format (pre-allocated)
+*    addr - trigger to be converted in packet format
+*
+*  output:
+*    length - length of the address in packet format
+*
+***************************************************************************/
+
+void pack_i3_addr(char *p, i3_addr *addr, unsigned short *length)
+{
+    unsigned short len = 0, l;
+    long long_temp;
+    short short_temp;
+
+    p[0] = addr->type;
+    p++;
+    len++;
+
+    switch (addr->type) {
+    case I3_ADDR_TYPE_STACK:
+        pack_i3_stack(p, addr->t.stack, &l);
+        len       += l;
+        break;
+
+    case I3_ADDR_TYPE_IPv4:
+        long_temp  = htonl(addr->t.v4.addr.s_addr);
+        memcpy(p, (char *) &long_temp, sizeof(long));
+        p         += sizeof(long);
+        len       += sizeof(long);
+
+        short_temp = htons(addr->t.v4.port);
+        memcpy(p, &short_temp, sizeof(short));
+        p         += sizeof(short);
+        len       += sizeof(short);
+
+        break;
+
+    case I3_ADDR_TYPE_IPv4_NAT:
+        long_temp  = htonl(addr->t.v4_nat.host_addr.s_addr);
+        memcpy(p, (char *) &long_temp, sizeof(long));
+        p         += sizeof(long);
+        len       += sizeof(long);
+        short_temp = htons(addr->t.v4_nat.host_port);
+        memcpy(p, &short_temp, sizeof(short));
+        p         += sizeof(short);
+        len       += sizeof(short);
+
+        long_temp  = htonl(addr->t.v4_nat.nat_addr.s_addr);
+        memcpy(p, (char *) &long_temp, sizeof(long));
+        p         += sizeof(long);
+        len       += sizeof(long);
+        short_temp = htons(addr->t.v4_nat.nat_port);
+        memcpy(p, &short_temp, sizeof(short));
+        p         += sizeof(short);
+        len       += sizeof(short);
+
+        long_temp  = htonl(addr->t.v4_nat.i3srv_addr.s_addr);
+        memcpy(p, (char *) &long_temp, sizeof(long));
+        p         += sizeof(long);
+        len       += sizeof(long);
+        short_temp = htons(addr->t.v4_nat.i3srv_port);
+        memcpy(p, &short_temp, sizeof(short));
+        p         += sizeof(short);
+        len       += sizeof(short);
+        break;
+
+#ifndef _WIN32
+    case I3_ADDR_TYPE_IPv6:
+#ifndef CCURED
+        memcpy(p, (char *) &addr->t.v6.addr.s6_addr, sizeof(struct in6_addr));
+#else
+        *(struct in6_addr *) p = addr->t.v6.addr;
+#endif
+        p                     += sizeof(struct in6_addr);
+        len                   += sizeof(struct in6_addr);
+
+        short_temp             = htons(addr->t.v6.port);
+        memcpy(p, &short_temp, sizeof(short));
+        len                   += sizeof(short);
+        p                     += sizeof(short);
+
+        break;
+#endif
+
+    default:
+        printf("pack_i3_addr: invalid address type %d\n", addr->type);
+    }
+
+    *length = len;
+}
+
+unsigned short get_i3_addr_len(i3_addr *addr)
+{
+    unsigned short length;
+
+    length = sizeof(char); /* type */
+
+    switch (addr->type) {
+    case I3_ADDR_TYPE_STACK:
+        length += get_i3_stack_len(addr->t.stack);
+        break;
+    case I3_ADDR_TYPE_IPv4:
+        length += sizeof(long) + sizeof(short);
+        break;
+    case I3_ADDR_TYPE_IPv4_NAT:
+        length += 3 * (sizeof(long) + sizeof(short));
+        break;
+#ifndef __CYGWIN__
+    case I3_ADDR_TYPE_IPv6:
+        length += sizeof(struct in6_addr) + sizeof(short);
+        break;
+#endif
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "pack_i3_addr: invalid address 
type %d\n", addr->type);
+    }
+
+    return length;
+}
+
+/***************************************************************************
+*  unpack_i3_addr - copy address info from packet to a trigger
+*                   data structure
+*
+*  input:
+*    p - address where address is stored in packet format
+*
+*  return:
+*    address data structure initialized with the info from buffer "p"
+*
+*  output:
+*    length - length of the address info in packet format
+*
+***************************************************************************/
+
+i3_addr *unpack_i3_addr(char *p, unsigned short *length)
+{
+    unsigned short len;
+    i3_addr *addr = alloc_i3_addr();
+
+    addr->type = p[0];
+    p++;
+    *length    = 1;
+
+    switch (addr->type) {
+    case I3_ADDR_TYPE_STACK:
+        addr->t.stack          = unpack_i3_stack(p, &len);
+        *length               += len;
+        break;
+
+    case I3_ADDR_TYPE_IPv4:
+        addr->t.v4.addr.s_addr = ntohl(*((long *) p));
+        p                     += sizeof(long);
+        *length               += sizeof(long);
+
+        addr->t.v4.port        = ntohs(*((short *) p));
+        *length               += sizeof(short);
+        p                     += sizeof(short);
+
+        break;
+
+    case I3_ADDR_TYPE_IPv4_NAT:
+        addr->t.v4_nat.host_addr.s_addr  = ntohl(*((long *) p));
+        p                               += sizeof(long);
+        *length                         += sizeof(long);
+        addr->t.v4_nat.host_port         = ntohs(*((short *) p));
+        *length                         += sizeof(short);
+        p                               += sizeof(short);
+
+        addr->t.v4_nat.nat_addr.s_addr   = ntohl(*((long *) p));
+        p                               += sizeof(long);
+        *length                         += sizeof(long);
+        addr->t.v4_nat.nat_port          = ntohs(*((short *) p));
+        *length                         += sizeof(short);
+        p                               += sizeof(short);
+
+        addr->t.v4_nat.i3srv_addr.s_addr = ntohl(*((long *) p));
+        p                               += sizeof(long);
+        *length                         += sizeof(long);
+        addr->t.v4_nat.i3srv_port        = ntohs(*((short *) p));
+        *length                         += sizeof(short);
+        p                               += sizeof(short);
+        break;
+
+#ifndef __CYGWIN__
+    case I3_ADDR_TYPE_IPv6:
+#ifndef CCURED
+        memcpy((char *) &addr->t.v6.addr.s6_addr, p, sizeof(struct in6_addr));
+#else
+        addr->t.v6.addr = *(struct in6_addr *) p;
+#endif
+
+        p              += sizeof(struct in6_addr);
+        *length        += sizeof(struct in6_addr);
+
+        addr->t.v6.port = ntohs(*((short *) p));
+        *length        += sizeof(short);
+        p              += sizeof(short);
+
+        break;
+#endif
+
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "unpack_i3_addr: invalid 
address type %d\n", addr->type);
+    }
+    return addr;
+}
+
+/***************************************************************************
+*  check_i3_addr - check address whether is well-formed
+*
+*  input:
+*    p - address where i3_addr is stored in packet format
+*
+*  return:
+*    error code; FALSE if no error
+*
+*  output:
+*    length - length of the address info in packet format
+*
+***************************************************************************/
+
+int check_i3_addr(char *p, unsigned short *length, char *type)
+{
+    *type = p[0];
+
+    p++; /* skip address type field */
+
+    switch (*type) {
+    case I3_ADDR_TYPE_STACK:
+        check_i3_stack(p, length);
+        break;
+    case I3_ADDR_TYPE_IPv4:
+        *length = sizeof(long) /*IP address*/ + sizeof(short) /*port*/;
+        break;
+    case I3_ADDR_TYPE_IPv4_NAT:
+        *length = 3 * (sizeof(long) /*IP address*/ + sizeof(short) /*port*/);
+        break;
+#ifndef __CYGWIN__
+    case I3_ADDR_TYPE_IPv6:
+        *length = sizeof(struct in6_addr) /*IP address*/ + sizeof(short) 
/*port*/;
+        break;
+#endif
+    default:
+        return I3_ERR_INVALID_ADDR;
+    }
+
+    *length += 1; /* account for address type */
+
+    return FALSE;
+}
+
+/**
+ * This function understands natted addresses.
+ * If an address is natted, the nat_address and nat_port number
+ * are used in the comparison.
+ * @author Dilip
+ */
+int addr_nat_equal(i3_addr *a1, i3_addr *a2)
+{
+    struct in_addr cmp_addr_A, cmp_addr_B;
+    int cmp_port_A = 0, cmp_port_B = 0;
+
+    memset(&cmp_addr_A, 0, sizeof(struct in_addr));
+    memset(&cmp_addr_B, 0, sizeof(struct in_addr));
+
+    if (a1->type == I3_ADDR_TYPE_IPv4) {
+        memcpy(&cmp_addr_A, &a1->t.v4.addr, sizeof(struct in_addr));
+        cmp_port_A = a1->t.v4.port;
+    } else if (a1->type == I3_ADDR_TYPE_IPv4_NAT) {
+        memcpy(&cmp_addr_A, &a1->t.v4_nat.host_addr, sizeof(struct in_addr));
+        cmp_port_A = a1->t.v4_nat.host_port;
+    }
+
+    if (a2->type == I3_ADDR_TYPE_IPv4) {
+        memcpy(&cmp_addr_B, &a2->t.v4.addr, sizeof(struct in_addr));
+        cmp_port_B = a2->t.v4.port;
+    } else if (a2->type == I3_ADDR_TYPE_IPv4_NAT) {
+        memcpy(&cmp_addr_B, &a2->t.v4_nat.host_addr, sizeof(struct in_addr));
+        cmp_port_B = a2->t.v4_nat.host_port;
+    }
+
+    if (cmp_addr_A.s_addr != cmp_addr_B.s_addr || cmp_port_A != cmp_port_B) {
+        return FALSE;
+    } else {
+        return TRUE;
+    }
+}
+
+/***************************************************************************
+*  addr_equal - compare two addresses
+*
+*  input:
+*    t1, t2 - addresses to be compared
+*
+*  return:
+*    TRUE, if the addresses are identical; FALSE, otherwise
+*
+***************************************************************************/
+
+int addr_equal(i3_addr *a1, i3_addr *a2)
+{
+#ifndef __CYGWIN__
+    uint i;
+#endif
+
+    if (a1->type != a2->type) {
+        return FALSE;
+    }
+
+    switch (a1->type) {
+    case I3_ADDR_TYPE_IPv4:
+        if ((a1->t.v4.addr.s_addr != a2->t.v4.addr.s_addr) ||
+            (a1->t.v4.port != a2->t.v4.port)) {
+            return FALSE;
+        }
+        break;
+    case I3_ADDR_TYPE_IPv4_NAT:
+        if ((a1->t.v4_nat.host_addr.s_addr != a2->t.v4_nat.host_addr.s_addr) ||
+            (a1->t.v4_nat.host_port != a2->t.v4_nat.host_port) ||
+            (a1->t.v4_nat.nat_addr.s_addr != a2->t.v4_nat.nat_addr.s_addr) ||
+            (a1->t.v4_nat.nat_port != a2->t.v4_nat.nat_port) ||
+            (a1->t.v4_nat.i3srv_addr.s_addr != a2->t.v4_nat.i3srv_addr.s_addr) 
||
+            (a1->t.v4_nat.i3srv_port != a2->t.v4_nat.i3srv_port)) {
+            return FALSE;
+        }
+        break;
+#ifndef __CYGWIN__
+    case I3_ADDR_TYPE_IPv6:
+        for (i = 0; i < sizeof(struct in6_addr); i++) {
+            if (a1->t.v6.addr.s6_addr[i] != a2->t.v6.addr.s6_addr[i]) {
+                return FALSE;
+            }
+        }
+        if (a1->t.v6.port == a2->t.v6.port) {
+            return FALSE;
+        }
+        break;
+#endif
+    case I3_ADDR_TYPE_STACK:
+        if (a1->t.stack->len != a2->t.stack->len) {
+            return FALSE;
+        }
+        if (memcmp((char *) a1->t.stack->ids, (char *) a2->t.stack->ids,
+                   a1->t.stack->len * sizeof(ID))) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+/***************************************************************************
+*  sizeof_addr - return the length of the address data structure
+*
+*  input:
+*    a - given address
+*
+*  return:
+*    length in bytes of the address
+*
+***************************************************************************/
+
+int sizeof_addr(i3_addr *a)
+{
+    switch (a->type) {
+    case I3_ADDR_TYPE_IPv4:
+        return sizeof(struct in_addr) + sizeof(uint16_t) + sizeof(a->type) +
+               KEY_LEN;
+    case I3_ADDR_TYPE_IPv4_NAT:
+        return 3 * (sizeof(struct in_addr) + sizeof(uint16_t)) + 
sizeof(a->type) +
+               KEY_LEN;
+#ifndef __CYGWIN__
+    case I3_ADDR_TYPE_IPv6:
+        return sizeof(struct in6_addr) + sizeof(uint16_t) + sizeof(a->type) +
+               KEY_LEN;
+#endif
+    case I3_ADDR_TYPE_STACK:
+        return a->t.stack->len * sizeof(ID) + sizeof(a->type);
+    }
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "addr_len: Invalid trigger type");
+    return -1;
+}
+
+/***************************************************************************
+ * printf_id - print i3-id with an indentation of "indent"
+ **************************************************************************/
+
+void printf_id(ID *id, int indent)
+{
+    uint i;
+    char buf[INDENT_BUF_LEN];
+
+    memset(buf, ' ', indent);
+    buf[indent] = 0;
+
+    printf("%s i3-id = ", buf);
+    for (i = 0; i < sizeof(ID); i++) {
+        printf("%02x", id->x[i]);
+    }
+    printf("\n");
+}
+
+/***************************************************************************
+ * printf_i3_addr - print i3-addr with an indentation of "indent"
+ **************************************************************************/
+
+void printf_i3_addr(i3_addr *addr, int indent)
+{
+#ifndef __CYGWIN__
+    uint i;
+#endif
+    char buf[INDENT_BUF_LEN];
+    struct in_addr ia;
+
+    memset(buf, ' ', indent);
+    buf[indent] = 0;
+
+    printf("%s addr type = %d\n", buf, addr->type);
+
+    switch (addr->type) {
+    case I3_ADDR_TYPE_STACK:
+        printf_i3_stack(addr->t.stack, indent);
+        break;
+    case I3_ADDR_TYPE_IPv4:
+        ia.s_addr = htonl(addr->t.v4.addr.s_addr);
+        printf("%s IPv4 (address, port) = (%s, %d)",
+               buf, inet_ntoa(ia), addr->t.v4.port);
+        break;
+    case I3_ADDR_TYPE_IPv4_NAT:
+        ia.s_addr = htonl(addr->t.v4_nat.host_addr.s_addr);
+        printf("%s NAT_IPv4 (host_addr, host_port) = (%s, %d)\n",
+               buf, inet_ntoa(ia), addr->t.v4_nat.host_port);
+        ia.s_addr = htonl(addr->t.v4_nat.nat_addr.s_addr);
+        printf("%s          (nat_addr, nat_port) = (%s, %d)\n",
+               buf, inet_ntoa(ia), addr->t.v4_nat.nat_port);
+        ia.s_addr = htonl(addr->t.v4_nat.i3srv_addr.s_addr);
+        printf("%s          (i3srv_addr, i3srv_port) = (%s, %d)\n",
+               buf, inet_ntoa(ia), addr->t.v4_nat.i3srv_port);
+        break;
+#ifndef __CYGWIN__
+    case I3_ADDR_TYPE_IPv6:
+        printf("%s IPv6 (address, port) = (", buf);
+        for (i = 0; i < sizeof(struct in6_addr); i++) {
+            printf("%d.", addr->t.v6.addr.s6_addr[i]);
+        }
+        printf(", %d)", addr->t.v6.port);
+        break;
+#endif
+    default:
+        printf("Unknown addr type\n");
+    }
+    printf("\n");
+}
+
+/***************************************************************************
+ * compute_nonce - compute the nonce for challenging trigger insertion
+ **************************************************************************/
+
+void compute_nonce(char *nonce, i3_addr *a)
+{
+    memset(nonce, 0, NONCE_LEN);
+
+    switch (a->type) {
+    case I3_ADDR_TYPE_IPv4:
+#ifndef CCURED
+        memcpy(nonce, (char *) &a->t.v4.addr.s_addr, sizeof(struct in_addr));
+#else
+        *(struct in_addr *) nonce = a->t.v4.addr;
+#endif
+#ifndef CCURED
+        memcpy(nonce + sizeof(struct in_addr),
+               (char *) &a->t.v4.port, sizeof(a->t.v4.port));
+#else
+        *(uint16_t *) (nonce + sizeof(struct in_addr)) = a->t.v4.port;
+#endif
+        break;
+    case I3_ADDR_TYPE_IPv4_NAT:
+        /* the 2nd address in the two-hop route represents the
+         * the Internet-routable address of the destination
+         */
+        memcpy(nonce, (char *) &a->t.v4_nat.nat_addr.s_addr,
+               sizeof(struct in_addr));
+        memcpy(nonce + sizeof(struct in_addr),
+               (char *) &a->t.v4_nat.host_port, sizeof(a->t.v4_nat.nat_port));
+        break;
+#ifndef __CYGWIN__
+    case I3_ADDR_TYPE_IPv6:
+#ifndef CCURED
+        memcpy(nonce, (char *) &a->t.v6.addr.s6_addr,
+               MIN(sizeof(struct in6_addr), NONCE_LEN));
+#else
+        {
+            struct in6_addr tmp = a->t.v6.addr;
+            memcpy(nonce, (char *) &tmp, MIN(sizeof(struct in6_addr), 
NONCE_LEN));
+        }
+#endif
+        break;
+#endif
+    case I3_ADDR_TYPE_STACK:
+        memcpy(nonce, a->t.stack->ids, NONCE_LEN);
+        break;
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "compute_nonce: invalid 
address type %d\n", a->type);
+        printf_i3_addr(a, 2);
+    }
+}

=== modified file 'i3/i3/i3_addr.h'
--- i3/i3/i3_addr.h     2010-01-06 22:17:32 +0000
+++ i3/i3/i3_addr.h     2010-02-11 11:49:47 +0000
@@ -1,38 +1,37 @@
-/***************************************************************************
-                          i3_addr.h  -  description
-                             -------------------
-    begin                : Fre Jun 20 2003
-    copyright            : (C) 2003 by klaus
-    email                : wehrle@xxxxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef I3_ADDR_H
-#define I3_ADDR_H
- 
-/* functions implemented in i3_addr.c */
-i3_addr *alloc_i3_addr(void);
-
-void init_i3_addr_ipv4(i3_addr *a, struct in_addr addr, uint16_t port);
-void init_i3_addr_ipv4_nat(i3_addr *a, 
-                          struct in_addr host_addr, uint16_t host_port,
-                          struct in_addr nat_addr, uint16_t nat_port,
-                          struct in_addr i3srv_addr, uint16_t i3srv_port);
-#ifndef __CYGWIN__
-void init_i3_addr_ipv6(i3_addr *a, struct in6_addr addr, uint16_t port);
-#endif
-void init_i3_addr_stack(i3_addr *a, i3_stack *s);
-i3_addr *duplicate_i3_addr(i3_addr *a);
-void free_i3_addr(i3_addr *addr);
-void pack_i3_addr(char *p, i3_addr *addr, unsigned short *length);
-unsigned short get_i3_addr_len(i3_addr *addr);
-i3_addr *unpack_i3_addr(char *p, unsigned short *length);
-int check_i3_addr(char *p, unsigned short *length, char *type);
-int addr_equal(i3_addr *a1, i3_addr *a2);
-int addr_nat_equal(i3_addr *a1, i3_addr *a2);
-int sizeof_addr(i3_addr *a);
-void printf_i3_addr(i3_addr *addr, int intend);
-void printf_id(ID *id, int indent);
-void compute_nonce(char *nonce, i3_addr *a);
-
-#endif
-
+/***************************************************************************
+*                         i3_addr.h  -  description
+*                            -------------------
+*   begin                : Fre Jun 20 2003
+*   copyright            : (C) 2003 by klaus
+*   email                : wehrle@xxxxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef I3_ADDR_H
+#define I3_ADDR_H
+
+/* functions implemented in i3_addr.c */
+i3_addr *alloc_i3_addr(void);
+
+void init_i3_addr_ipv4(i3_addr *a, struct in_addr addr, uint16_t port);
+void init_i3_addr_ipv4_nat(i3_addr *a,
+                           struct in_addr host_addr, uint16_t host_port,
+                           struct in_addr nat_addr, uint16_t nat_port,
+                           struct in_addr i3srv_addr, uint16_t i3srv_port);
+#ifndef __CYGWIN__
+void init_i3_addr_ipv6(i3_addr *a, struct in6_addr addr, uint16_t port);
+#endif
+void init_i3_addr_stack(i3_addr *a, i3_stack *s);
+i3_addr *duplicate_i3_addr(i3_addr *a);
+void free_i3_addr(i3_addr *addr);
+void pack_i3_addr(char *p, i3_addr *addr, unsigned short *length);
+unsigned short get_i3_addr_len(i3_addr *addr);
+i3_addr *unpack_i3_addr(char *p, unsigned short *length);
+int check_i3_addr(char *p, unsigned short *length, char *type);
+int addr_equal(i3_addr *a1, i3_addr *a2);
+int addr_nat_equal(i3_addr *a1, i3_addr *a2);
+int sizeof_addr(i3_addr *a);
+void printf_i3_addr(i3_addr *addr, int intend);
+void printf_id(ID *id, int indent);
+void compute_nonce(char *nonce, i3_addr *a);
+
+#endif

=== modified file 'i3/i3/i3_api.c'
--- i3/i3/i3_api.c      2009-12-11 22:49:11 +0000
+++ i3/i3/i3_api.c      2010-02-11 11:49:47 +0000
@@ -1,53 +1,52 @@
-/** @file
- *
- * @note: HIPU: libinet6 requires LD_PRELOAD which is "dylib" on BSD.
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <sys/types.h>   /* basic system data types */
-
-#include <errno.h>    
-#include "../utils/netwrap.h"
-
-#include "i3.h"
-#include "i3_fun.h"
-#include "i3_debug.h"
-
-int id_local(char *id)
-{
-  // to be changed when more than one server
-  return TRUE; 
-}
-
-void send_packet_ipv4(char *pkt, int len, struct in_addr *dst_addr, 
-                     uint16_t dst_port, nw_skt_t dst_fd)
-{
-  struct sockaddr_in dstaddr;
-
-  memset(&dstaddr, 0, sizeof(dstaddr));
-  dstaddr.sin_family = AF_INET;
-  dstaddr.sin_addr.s_addr = htonl(dst_addr->s_addr);
-  dstaddr.sin_port = htons(dst_port);
-
-  if (sendto(dst_fd, pkt, len, 0, 
-            (struct sockaddr *)&dstaddr, sizeof(dstaddr)) < 0)
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "send_ipv4: sendto error\n");
-}
-
-#ifndef __CYGWIN__
-void send_packet_ipv6(char *p, int len, 
-                     struct in6_addr *ip6_addr, uint16_t port, nw_skt_t rfd)
-{
-    I3_PRINT_INFO0(I3_INFO_LEVEL_WARNING, "send_packet_ipv6: not implemented 
yet!\n");
-}
-#endif
-
-void send_packet_i3(char *p, int len)
-{
-    I3_PRINT_INFO0(I3_INFO_LEVEL_WARNING, "send_i3: not implemented yet!\n");
-}
-
-
-
+/** @file
+ *
+ * @note: HIPU: libinet6 requires LD_PRELOAD which is "dylib" on BSD.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>   /* basic system data types */
+
+#include <errno.h>
+#include "../utils/netwrap.h"
+
+#include "i3.h"
+#include "i3_fun.h"
+#include "i3_debug.h"
+
+int id_local(char *id)
+{
+    // to be changed when more than one server
+    return TRUE;
+}
+
+void send_packet_ipv4(char *pkt, int len, struct in_addr *dst_addr,
+                      uint16_t dst_port, nw_skt_t dst_fd)
+{
+    struct sockaddr_in dstaddr;
+
+    memset(&dstaddr, 0, sizeof(dstaddr));
+    dstaddr.sin_family      = AF_INET;
+    dstaddr.sin_addr.s_addr = htonl(dst_addr->s_addr);
+    dstaddr.sin_port        = htons(dst_port);
+
+    if (sendto(dst_fd, pkt, len, 0,
+               (struct sockaddr *) &dstaddr, sizeof(dstaddr)) < 0) {
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "send_ipv4: sendto error\n");
+    }
+}
+
+#ifndef __CYGWIN__
+void send_packet_ipv6(char *p, int len,
+                      struct in6_addr *ip6_addr, uint16_t port, nw_skt_t rfd)
+{
+    I3_PRINT_INFO0(I3_INFO_LEVEL_WARNING, "send_packet_ipv6: not implemented 
yet!\n");
+}
+
+#endif
+
+void send_packet_i3(char *p, int len)
+{
+    I3_PRINT_INFO0(I3_INFO_LEVEL_WARNING, "send_i3: not implemented yet!\n");
+}

=== modified file 'i3/i3/i3_api.h'
--- i3/i3/i3_api.h      2009-12-11 22:49:11 +0000
+++ i3/i3/i3_api.h      2010-02-11 11:49:47 +0000
@@ -1,18 +1,18 @@
-/***************************************************************************
- *                     i3_addr.h  -  description
- **************************************************************************/
-
-#ifndef I3_API_H
-#define I3_API_H
-#include "../utils/netwrap.h"
-
-int id_local(char *id);
-void send_packet_ipv4(char *pkt, int len, struct in_addr *dst_addr, 
-                     uint16_t dst_port, nw_skt_t dst_fd);
-#ifndef __CYGWIN__
-void send_packet_ipv6(char *p, int len, 
-                     struct in6_addr *ip6_addr, uint16_t port, nw_skt_t rfd);
-#endif
-void send_packet_i3(char *p, int len);
-
-#endif //I3_API_H
+/***************************************************************************
+ *          i3_addr.h  -  description
+ **************************************************************************/
+
+#ifndef I3_API_H
+#define I3_API_H
+#include "../utils/netwrap.h"
+
+int id_local(char *id);
+void send_packet_ipv4(char *pkt, int len, struct in_addr *dst_addr,
+                      uint16_t dst_port, nw_skt_t dst_fd);
+#ifndef __CYGWIN__
+void send_packet_ipv6(char *p, int len,
+                      struct in6_addr *ip6_addr, uint16_t port, nw_skt_t rfd);
+#endif
+void send_packet_i3(char *p, int len);
+
+#endif //I3_API_H

=== modified file 'i3/i3/i3_config.c'
--- i3/i3/i3_config.c   2010-01-06 22:17:32 +0000
+++ i3/i3/i3_config.c   2010-02-11 11:49:47 +0000
@@ -1,300 +1,291 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <libxml2/libxml/xmlmemory.h>
-#include <libxml2/libxml/parser.h>
-#include <libxml2/libxml/tree.h>
-#include <libxml2/libxml/xpath.h>
-#include <ctype.h>
-#include "i3_debug.h"
-#include "i3_config.h"
-
-static xmlDocPtr i3_config_doc;
-char cfilename[200]="";
-
-void read_parameters(const char* filename)
-{
-  char version[200];
-  xmlNodePtr root;
-  strcpy(cfilename,filename);
-
-  i3_config_doc = xmlParseFile(filename);
-
-  if (i3_config_doc == NULL )
-  {
-    I3_PRINT_INFO1(
-           I3_INFO_LEVEL_FATAL_ERROR,
-           "%s: XML configuration in not parsed successfully"
-           "check whether all tags are terminated etc). \n",
-           filename
-       );
-    exit(-1);
-  }
-
-  root = xmlDocGetRootElement(i3_config_doc);
-
-  if (root == NULL)
-  {
-    I3_PRINT_INFO1(
-           I3_INFO_LEVEL_FATAL_ERROR,
-           "%s: Empty XML configuration file\n",
-           filename
-           );
-    exit(-1);
-  }
-
-  if (xmlStrcmp(root->name, (const xmlChar *) "I3ConfigFile")) {
-    I3_PRINT_INFO1(
-           I3_INFO_LEVEL_FATAL_ERROR,
-           "%s: Document of the wrong type, root node != I3ConfigFile\n",
-           filename
-       );
-    exit(-1);
-  }
-
-  read_string_attribute("//I3ConfigFile", "version",version,1);
-
-  if ( strcmp(version,VER_CONFIG))
-  {
-    I3_PRINT_INFO3(
-           I3_INFO_LEVEL_FATAL_ERROR,
-           "%s: Incorrect version of configuration file. "
-           "This code uses version %s configuration file, your configuration "
-           "file has version %s, please update.\n",
-           filename,VER_CONFIG,version
-       );
-    exit(-1);
-  }
-
-}
-
-void release_params()
-{
-  xmlFreeDoc(i3_config_doc);
-  //xmlCleanupParser();
-}
-
-xmlXPathObjectPtr getnodeset(xmlChar *xpath)
-{
-  xmlXPathContextPtr context;
-  xmlXPathObjectPtr result;
-
-  context = xmlXPathNewContext(i3_config_doc);
-  result = xmlXPathEvalExpression(xpath, context);
-  
-  if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
-    xmlXPathFreeObject(result);
-    xmlXPathFreeContext(context);
-    return NULL;
-  }
-
-  xmlXPathFreeContext(context);
-  return result;
-}
-
-void strip_ws(char* str)
-{
-  char tstr[200];
-  int lindex = 0;
-  int rindex = 0;
-
-  while ( str[lindex] != 0 && isspace(str[lindex]))
-    lindex++;
-
-  rindex = ((int) strlen(str)) -1;
-  while ( rindex >= 0 && isspace(str[rindex]) )
-    rindex--;
-
-  if ( lindex == strlen(str))
-  {
-    strcpy(str,"");
-    return;
-  }
-
-  str[rindex+1] = 0;
-  strcpy(tstr,str+lindex);
-  strcpy(str,tstr);
-}
-
-
-void read_string_attribute(char* elementPath, char *attribName, char* str, int 
required)
-{
-  xmlChar *xpath;
-  xmlXPathObjectPtr result;
-  xmlNodeSetPtr nodeset;
-  xmlChar* resultstr;
-  char tmpBuf[1000];
-  sprintf(tmpBuf, "%s[@%s]", elementPath, attribName);
-
-  xpath = xmlCharStrdup(tmpBuf);
-  result = getnodeset(xpath);
-  xmlFree(xpath);
-
-  required=1;
-
-  if ( required && result == NULL )
-  {
-    printf("%s: %s required in configuration file\n",cfilename, elementPath);
-    exit(-1);
-  }
-
-  if ( result == NULL )
-    return;
-  nodeset = result->nodesetval;
-
-  if ( nodeset->nodeNr >= 2 )
-  {
-    I3_PRINT_INFO2(
-           I3_INFO_LEVEL_FATAL_ERROR,
-           "%s: %s should appear atmost once in configuration file\n",
-           cfilename, elementPath
-       );
-    exit(-1);
-  }
-
-  resultstr = xmlGetProp(nodeset->nodeTab[0], (xmlChar*)attribName);
-  strcpy(str,(char*)resultstr);
-  strip_ws(str);
-  xmlFree(resultstr);
-  xmlXPathFreeObject(result);
-}
-
-void read_string_par(char* path,char* str,int required)
-{
-  xmlNodeSetPtr nodeset;
-  xmlChar* resultstr;
-  xmlChar *xpath = xmlCharStrdup(path);
-  xmlXPathObjectPtr result = getnodeset(xpath);
-  xmlFree(xpath);
-
-  required=1;
-
-  if ( required && result == NULL )
-  {
-    printf("%s: %s required in configuration file\n",cfilename,path);
-    exit(-1);
-  }
-
-  if ( result == NULL )
-    return;
-
-  nodeset = result->nodesetval;
-
-  if ( nodeset->nodeNr >= 2 )
-  {
-    I3_PRINT_INFO2(
-           I3_INFO_LEVEL_FATAL_ERROR,
-           "%s: %s should appear atmost once in configuration file\n",
-           cfilename,path
-       );
-    exit(-1);
-  }
-
-  resultstr = xmlNodeListGetString(i3_config_doc, 
nodeset->nodeTab[0]->xmlChildrenNode, 1);
-  strcpy(str,(char*)resultstr);
-  strip_ws(str);
-  xmlFree(resultstr);
-  xmlXPathFreeObject(result);
-}
-
-void read_ushort_attribute(char* elementPath, char *attribName,unsigned short* 
us,int required)
-{
-  char str[200];
-  read_string_attribute(elementPath, attribName, str,required);
-  *us = (unsigned short) atoi(str);
-}
-
-void read_ushort_par(char* path,unsigned short* us,int required)
-{
-  char str[200];
-  read_string_par(path,str,required);
-  *us = (unsigned short) atoi(str);
-}
-
-char **read_i3server_list(int* num)
-{
-  xmlNodeSetPtr nodeset;
-  char** toret;
-  int i;
-  xmlChar *xpath = xmlCharStrdup("//I3Server");
-  xmlXPathObjectPtr result = getnodeset(xpath);
-  xmlFree(xpath);
-
-  if ( result == NULL )
-  {
-    *num=0;
-    return NULL;
-  }
-
-  nodeset = result->nodesetval;
-  toret = (char**) malloc(nodeset->nodeNr * sizeof(char*));
-  *num=nodeset->nodeNr;
-
-  for(i=0;i<nodeset->nodeNr;i++)
-  {
-    xmlChar* ipStr = xmlGetProp(nodeset->nodeTab[i], (xmlChar*) "IPAddress");
-    xmlChar* portStr = xmlGetProp(nodeset->nodeTab[i], (xmlChar*) "PortNum");
-    xmlChar* i3IdStr = xmlGetProp(nodeset->nodeTab[i], (xmlChar*) "I3Id");
-
-    toret[i] = (char *) malloc(1000);  /* TODO */
-    sprintf(toret[i], "%s %s %s\n", (char *) ipStr, (char *) portStr, (char *) 
i3IdStr);
-
-    strip_ws(toret[i]);
-    xmlFree(ipStr);
-    xmlFree(portStr);
-    xmlFree(i3IdStr);
-  }
-
-  xmlXPathFreeObject (result);
-  return toret;
-}
-
-char **read_strings_par(char* path,int* num)
-{
-  xmlNodeSetPtr nodeset;
-  char** toret;
-  int i;
-  xmlChar *xpath = xmlCharStrdup(path);
-  xmlXPathObjectPtr result = getnodeset(xpath);
-  xmlFree(xpath);
-
-  if ( result == NULL )
-  {
-    *num=0;
-    return NULL;
-  }
-
-  nodeset = result->nodesetval;
-  toret = (char**) malloc(nodeset->nodeNr * sizeof(char*));
-  *num=nodeset->nodeNr;
-
-  for(i=0;i<nodeset->nodeNr;i++)
-  {
-    xmlChar* resultstr = xmlNodeListGetString(i3_config_doc, 
nodeset->nodeTab[i]->xmlChildrenNode, 1);
-    toret[i] = strdup((char*)resultstr);
-    strip_ws(toret[i]);
-    xmlFree(resultstr);
-  }
-
-  xmlXPathFreeObject (result);
-  return toret;
-}
-
-int test_main(void)
-{
-  char fake[200];
-  char** fakes;
-  int num;
-  int i;
-
-  read_parameters("i3-proxy.xml");
-  
read_string_par("/parameters/proxy/server_proxy_trigger/server_proxy[@name='sp1']",fake,1);
-  printf("%s\n",fake);
-
-  fakes = read_strings_par("/parameters/proxy/public_triggers/trigger",&num);
-  printf("Num: %d\n",num);
-  for(i=0;i<num;i++)
-    printf("%s\n",fakes[i]);
-
-  return 0;
-}
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libxml2/libxml/xmlmemory.h>
+#include <libxml2/libxml/parser.h>
+#include <libxml2/libxml/tree.h>
+#include <libxml2/libxml/xpath.h>
+#include <ctype.h>
+#include "i3_debug.h"
+#include "i3_config.h"
+
+static xmlDocPtr i3_config_doc;
+char cfilename[200] = "";
+
+void read_parameters(const char *filename)
+{
+    char version[200];
+    xmlNodePtr root;
+    strcpy(cfilename, filename);
+
+    i3_config_doc = xmlParseFile(filename);
+
+    if (i3_config_doc == NULL) {
+        I3_PRINT_INFO1(
+            I3_INFO_LEVEL_FATAL_ERROR,
+            "%s: XML configuration in not parsed successfully"
+            "check whether all tags are terminated etc). \n",
+            filename
+            );
+        exit(-1);
+    }
+
+    root = xmlDocGetRootElement(i3_config_doc);
+
+    if (root == NULL) {
+        I3_PRINT_INFO1(
+            I3_INFO_LEVEL_FATAL_ERROR,
+            "%s: Empty XML configuration file\n",
+            filename
+            );
+        exit(-1);
+    }
+
+    if (xmlStrcmp(root->name, (const xmlChar *) "I3ConfigFile")) {
+        I3_PRINT_INFO1(
+            I3_INFO_LEVEL_FATAL_ERROR,
+            "%s: Document of the wrong type, root node != I3ConfigFile\n",
+            filename
+            );
+        exit(-1);
+    }
+
+    read_string_attribute("//I3ConfigFile", "version", version, 1);
+
+    if (strcmp(version, VER_CONFIG)) {
+        I3_PRINT_INFO3(
+            I3_INFO_LEVEL_FATAL_ERROR,
+            "%s: Incorrect version of configuration file. "
+            "This code uses version %s configuration file, your configuration "
+            "file has version %s, please update.\n",
+            filename, VER_CONFIG, version
+            );
+        exit(-1);
+    }
+}
+
+void release_params()
+{
+    xmlFreeDoc(i3_config_doc);
+    //xmlCleanupParser();
+}
+
+xmlXPathObjectPtr getnodeset(xmlChar *xpath)
+{
+    xmlXPathContextPtr context;
+    xmlXPathObjectPtr result;
+
+    context = xmlXPathNewContext(i3_config_doc);
+    result  = xmlXPathEvalExpression(xpath, context);
+
+    if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {
+        xmlXPathFreeObject(result);
+        xmlXPathFreeContext(context);
+        return NULL;
+    }
+
+    xmlXPathFreeContext(context);
+    return result;
+}
+
+void strip_ws(char *str)
+{
+    char tstr[200];
+    int lindex = 0;
+    int rindex = 0;
+
+    while (str[lindex] != 0 && isspace(str[lindex])) {
+        lindex++;
+    }
+
+    rindex = ((int) strlen(str)) - 1;
+    while (rindex >= 0 && isspace(str[rindex])) {
+        rindex--;
+    }
+
+    if (lindex == strlen(str)) {
+        strcpy(str, "");
+        return;
+    }
+
+    str[rindex + 1] = 0;
+    strcpy(tstr, str + lindex);
+    strcpy(str, tstr);
+}
+
+void read_string_attribute(char *elementPath, char *attribName, char *str, int 
required)
+{
+    xmlChar *xpath;
+    xmlXPathObjectPtr result;
+    xmlNodeSetPtr nodeset;
+    xmlChar *resultstr;
+    char tmpBuf[1000];
+    sprintf(tmpBuf, "%s[@%s]", elementPath, attribName);
+
+    xpath    = xmlCharStrdup(tmpBuf);
+    result   = getnodeset(xpath);
+    xmlFree(xpath);
+
+    required = 1;
+
+    if (required && result == NULL) {
+        printf("%s: %s required in configuration file\n", cfilename, 
elementPath);
+        exit(-1);
+    }
+
+    if (result == NULL) {
+        return;
+    }
+    nodeset = result->nodesetval;
+
+    if (nodeset->nodeNr >= 2) {
+        I3_PRINT_INFO2(
+            I3_INFO_LEVEL_FATAL_ERROR,
+            "%s: %s should appear atmost once in configuration file\n",
+            cfilename, elementPath
+            );
+        exit(-1);
+    }
+
+    resultstr = xmlGetProp(nodeset->nodeTab[0], (xmlChar *) attribName);
+    strcpy(str, (char *) resultstr);
+    strip_ws(str);
+    xmlFree(resultstr);
+    xmlXPathFreeObject(result);
+}
+
+void read_string_par(char *path, char *str, int required)
+{
+    xmlNodeSetPtr nodeset;
+    xmlChar *resultstr;
+    xmlChar *xpath           = xmlCharStrdup(path);
+    xmlXPathObjectPtr result = getnodeset(xpath);
+    xmlFree(xpath);
+
+    required = 1;
+
+    if (required && result == NULL) {
+        printf("%s: %s required in configuration file\n", cfilename, path);
+        exit(-1);
+    }
+
+    if (result == NULL) {
+        return;
+    }
+
+    nodeset = result->nodesetval;
+
+    if (nodeset->nodeNr >= 2) {
+        I3_PRINT_INFO2(
+            I3_INFO_LEVEL_FATAL_ERROR,
+            "%s: %s should appear atmost once in configuration file\n",
+            cfilename, path
+            );
+        exit(-1);
+    }
+
+    resultstr = xmlNodeListGetString(i3_config_doc, 
nodeset->nodeTab[0]->xmlChildrenNode, 1);
+    strcpy(str, (char *) resultstr);
+    strip_ws(str);
+    xmlFree(resultstr);
+    xmlXPathFreeObject(result);
+}
+
+void read_ushort_attribute(char *elementPath, char *attribName, unsigned short 
*us, int required)
+{
+    char str[200];
+    read_string_attribute(elementPath, attribName, str, required);
+    *us = (unsigned short) atoi(str);
+}
+
+void read_ushort_par(char *path, unsigned short *us, int required)
+{
+    char str[200];
+    read_string_par(path, str, required);
+    *us = (unsigned short) atoi(str);
+}
+
+char **read_i3server_list(int *num)
+{
+    xmlNodeSetPtr nodeset;
+    char **toret;
+    int i;
+    xmlChar *xpath           = xmlCharStrdup("//I3Server");
+    xmlXPathObjectPtr result = getnodeset(xpath);
+    xmlFree(xpath);
+
+    if (result == NULL) {
+        *num = 0;
+        return NULL;
+    }
+
+    nodeset = result->nodesetval;
+    toret   = (char **) malloc(nodeset->nodeNr * sizeof(char *));
+    *num    = nodeset->nodeNr;
+
+    for (i = 0; i < nodeset->nodeNr; i++) {
+        xmlChar *ipStr   = xmlGetProp(nodeset->nodeTab[i], (xmlChar *) 
"IPAddress");
+        xmlChar *portStr = xmlGetProp(nodeset->nodeTab[i], (xmlChar *) 
"PortNum");
+        xmlChar *i3IdStr = xmlGetProp(nodeset->nodeTab[i], (xmlChar *) "I3Id");
+
+        toret[i] = (char *) malloc(1000); /* TODO */
+        sprintf(toret[i], "%s %s %s\n", (char *) ipStr, (char *) portStr, 
(char *) i3IdStr);
+
+        strip_ws(toret[i]);
+        xmlFree(ipStr);
+        xmlFree(portStr);
+        xmlFree(i3IdStr);
+    }
+
+    xmlXPathFreeObject(result);
+    return toret;
+}
+
+char **read_strings_par(char *path, int *num)
+{
+    xmlNodeSetPtr nodeset;
+    char **toret;
+    int i;
+    xmlChar *xpath           = xmlCharStrdup(path);
+    xmlXPathObjectPtr result = getnodeset(xpath);
+    xmlFree(xpath);
+
+    if (result == NULL) {
+        *num = 0;
+        return NULL;
+    }
+
+    nodeset = result->nodesetval;
+    toret   = (char **) malloc(nodeset->nodeNr * sizeof(char *));
+    *num    = nodeset->nodeNr;
+
+    for (i = 0; i < nodeset->nodeNr; i++) {
+        xmlChar *resultstr = xmlNodeListGetString(i3_config_doc, 
nodeset->nodeTab[i]->xmlChildrenNode, 1);
+        toret[i] = strdup((char *) resultstr);
+        strip_ws(toret[i]);
+        xmlFree(resultstr);
+    }
+
+    xmlXPathFreeObject(result);
+    return toret;
+}
+
+int test_main(void)
+{
+    char fake[200];
+    char **fakes;
+    int num;
+    int i;
+
+    read_parameters("i3-proxy.xml");
+    
read_string_par("/parameters/proxy/server_proxy_trigger/server_proxy[@name='sp1']",
 fake, 1);
+    printf("%s\n", fake);
+
+    fakes = read_strings_par("/parameters/proxy/public_triggers/trigger", 
&num);
+    printf("Num: %d\n", num);
+    for (i = 0; i < num; i++) {
+        printf("%s\n", fakes[i]);
+    }
+
+    return 0;
+}

=== modified file 'i3/i3/i3_config.h'
--- i3/i3/i3_config.h   2010-01-06 22:17:32 +0000
+++ i3/i3/i3_config.h   2010-02-11 11:49:47 +0000
@@ -1,27 +1,27 @@
-#ifndef I3_CONFIG
-
-#define I3_CONFIG
-
-#define MAX_CONFIG_PARM_LEN 200
-#define VER_CONFIG "0.1"
-
-void read_parameters(const char* filename);
-void release_params(void);
-/* You need to preallocate str */
-void read_string_par(char* path,char* str,int required);
-/* You need to preallocate us */
-void read_ushort_par(char* path,unsigned short* us,int required);
-/* You need to deallocate the returned char** by first deallocating #num char* 
pointers, and then char** */
-char **read_strings_par(char* path,int* num);
-
-/** Read the (string) value of the attribute (attribName) of the element 
specificed by elementPath */
-void read_string_attribute(char* elementPath, char *attribName, char* str, int 
required);
-
-/** Read the (unsigned short) value of the attribute (attribName) of the 
element specificed by elementPath */
-void read_ushort_attribute(char* elementPath, char *attribName,unsigned short* 
us,int required);
-
-/** Read the list of i3 servers.  The number of servers is returned in the 
parameter num.
- */
-char **read_i3server_list(int* num);
-
-#endif
+#ifndef I3_CONFIG
+
+#define I3_CONFIG
+
+#define MAX_CONFIG_PARM_LEN 200
+#define VER_CONFIG "0.1"
+
+void read_parameters(const char *filename);
+void release_params(void);
+/* You need to preallocate str */
+void read_string_par(char *path, char *str, int required);
+/* You need to preallocate us */
+void read_ushort_par(char *path, unsigned short *us, int required);
+/* You need to deallocate the returned char** by first deallocating #num char* 
pointers, and then char** */
+char **read_strings_par(char *path, int *num);
+
+/** Read the (string) value of the attribute (attribName) of the element 
specificed by elementPath */
+void read_string_attribute(char *elementPath, char *attribName, char *str, int 
required);
+
+/** Read the (unsigned short) value of the attribute (attribName) of the 
element specificed by elementPath */
+void read_ushort_attribute(char *elementPath, char *attribName, unsigned short 
*us, int required);
+
+/** Read the list of i3 servers.  The number of servers is returned in the 
parameter num.
+ */
+char **read_i3server_list(int *num);
+
+#endif

=== modified file 'i3/i3/i3_debug.c'
--- i3/i3/i3_debug.c    2009-12-11 22:49:11 +0000
+++ i3/i3/i3_debug.c    2010-02-11 11:49:47 +0000
@@ -1,10 +1,10 @@
-#ifdef _WIN32
-
-
-// All the i3 debug and info messages go into this file.
-#      include <stdio.h>
-       // NOTE: the i3DebugFD should NOT be called debugFD.
-       // This causes a weird conflict with the debugging messages
-       // associated with the proxy
-       FILE* i3DebugFD = NULL;
-#endif
+#ifdef _WIN32
+
+
+// All the i3 debug and info messages go into this file.
+#       include <stdio.h>
+// NOTE: the i3DebugFD should NOT be called debugFD.
+// This causes a weird conflict with the debugging messages
+// associated with the proxy
+FILE *i3DebugFD = NULL;
+#endif

=== modified file 'i3/i3/i3_debug.h'
--- i3/i3/i3_debug.h    2009-12-11 22:49:11 +0000
+++ i3/i3/i3_debug.h    2010-02-11 11:49:47 +0000
@@ -1,89 +1,88 @@
-#ifndef I3_DEBUG_H
-#define I3_DEBUG_H 1
-
-#ifdef _WIN32
-#include <stdio.h>
-#      ifdef __cplusplus
-               extern "C" FILE* i3DebugFD;
-#      else
-               extern FILE* i3DebugFD;
-#      endif
-#endif
-
-
-/**
-  * The current debug level.
-  * Only debug messages with level less than or equal to this value will
-  * be printed.
-  */
-#define I3_CURRENT_DEBUG_LEVEL 100
-
-/**
-  * The current info level. This is used to restrict the amount of
-  * informational messages displayed to the user.
-  * Only those messages whose level is less than or equal to the
-  * CURRENT_INFO_LEVEL will be displayed.
-  */
-#define I3_CURRENT_INFO_LEVEL  100
-
-
-/**
-  * This file defines the constants used as debugging levels
-  * in the i3 specific code.
-  */
-
-/**
-  * This info level is used for displaying fatal error messages.
-  * Always displayed.
-  */
-#define I3_INFO_LEVEL_FATAL_ERROR 0
-
-/**
-  * This info level is used for messages which are very essential.
-  * Messages at this level will always be displayed.
-  */
-#define I3_INFO_LEVEL_MINIMAL  50
-
-/**
-  * This info level is used for warning messages.
-  */
-#define I3_INFO_LEVEL_WARNING  60
-
-/**
-  * The messages at this level are not critical.  So they may not be
-  * displayed (depends on CURRENT_INFO_LEVEL).
-  */
-#define I3_INFO_LEVEL_VERBOSE  70
-
-/**
-  * This is used for error messages which are probably caused due to bugs in 
the 
-  * code.  i.e. they are not INFO_LEVEL_WARNINGs
-  */
-#define I3_DEBUG_LEVEL_WARNING   20
-
-/**
- * This level is used temporarily while debugging to emphasize
- * certain parts of the code.
- */
-#define I3_DEBUG_LEVEL_SUPER   -1
-
-/**
-  * This is used for messages describing fatal errors.
-  */
-#define I3_DEBUG_LEVEL_FATAL   0
-
-/**
-  * This is used for messages that are not fatal, but quite important
-  * or high level.
-  */
-#define I3_DEBUG_LEVEL_MINIMAL     30
-
-/**
-  * This is used for messages that are not very important.
-  */
-#define I3_DEBUG_LEVEL_VERBOSE     90
-
-#include "debug_fns.h"
-
-#endif
-
+#ifndef I3_DEBUG_H
+#define I3_DEBUG_H 1
+
+#ifdef _WIN32
+#include <stdio.h>
+#       ifdef __cplusplus
+extern "C" FILE * i3DebugFD;
+#       else
+extern FILE *i3DebugFD;
+#       endif
+#endif
+
+
+/**
+ * The current debug level.
+ * Only debug messages with level less than or equal to this value will
+ * be printed.
+ */
+#define I3_CURRENT_DEBUG_LEVEL 100
+
+/**
+ * The current info level. This is used to restrict the amount of
+ * informational messages displayed to the user.
+ * Only those messages whose level is less than or equal to the
+ * CURRENT_INFO_LEVEL will be displayed.
+ */
+#define I3_CURRENT_INFO_LEVEL  100
+
+
+/**
+ * This file defines the constants used as debugging levels
+ * in the i3 specific code.
+ */
+
+/**
+ * This info level is used for displaying fatal error messages.
+ * Always displayed.
+ */
+#define I3_INFO_LEVEL_FATAL_ERROR 0
+
+/**
+ * This info level is used for messages which are very essential.
+ * Messages at this level will always be displayed.
+ */
+#define I3_INFO_LEVEL_MINIMAL  50
+
+/**
+ * This info level is used for warning messages.
+ */
+#define I3_INFO_LEVEL_WARNING  60
+
+/**
+ * The messages at this level are not critical.  So they may not be
+ * displayed (depends on CURRENT_INFO_LEVEL).
+ */
+#define I3_INFO_LEVEL_VERBOSE  70
+
+/**
+ * This is used for error messages which are probably caused due to bugs in the
+ * code.  i.e. they are not INFO_LEVEL_WARNINGs
+ */
+#define I3_DEBUG_LEVEL_WARNING   20
+
+/**
+ * This level is used temporarily while debugging to emphasize
+ * certain parts of the code.
+ */
+#define I3_DEBUG_LEVEL_SUPER   -1
+
+/**
+ * This is used for messages describing fatal errors.
+ */
+#define I3_DEBUG_LEVEL_FATAL   0
+
+/**
+ * This is used for messages that are not fatal, but quite important
+ * or high level.
+ */
+#define I3_DEBUG_LEVEL_MINIMAL     30
+
+/**
+ * This is used for messages that are not very important.
+ */
+#define I3_DEBUG_LEVEL_VERBOSE     90
+
+#include "debug_fns.h"
+
+#endif

=== modified file 'i3/i3/i3_fun.h'
--- i3/i3/i3_fun.h      2009-12-11 22:49:11 +0000
+++ i3/i3/i3_fun.h      2010-02-11 11:49:47 +0000
@@ -1,15 +1,15 @@
-#ifndef INCL_I3_FUN
-#define INCL_I3_FUN
-
-#include "i3_id.h"
-#include "i3_addr.h"
-#include "i3_header.h"
-#include "i3_misc.h"
-#include "i3_options.h"
-#include "i3_stack.h"
-#include "i3_trigger.h"
-#include "i3_api.h"
-#include "i3_utils.h"
-#include "token_bucket.h"
-
-#endif /* INCL_I3_FUN */
+#ifndef INCL_I3_FUN
+#define INCL_I3_FUN
+
+#include "i3_id.h"
+#include "i3_addr.h"
+#include "i3_header.h"
+#include "i3_misc.h"
+#include "i3_options.h"
+#include "i3_stack.h"
+#include "i3_trigger.h"
+#include "i3_api.h"
+#include "i3_utils.h"
+#include "token_bucket.h"
+
+#endif /* INCL_I3_FUN */

=== modified file 'i3/i3/i3_header.c'
--- i3/i3/i3_header.c   2009-12-11 22:49:11 +0000
+++ i3/i3/i3_header.c   2010-02-11 11:49:47 +0000
@@ -1,297 +1,315 @@
-/***************************************************************************
-                          i3_header.c  -  description
-                             -------------------
-    begin                : Nov 27 2002
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#include "i3.h"
-#include "i3_fun.h"
-#include "i3_debug.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-
-/***************************************************************************
- *  alloc_i3_header - allocate i3 header data structure
- *
- *  return:
- *    pointer to the allocated data structure 
- ***************************************************************************/
-
-i3_header *alloc_i3_header()
-{
-  struct i3_header *hdr;
-
-  /* XXX: just simply call alloc for now; preallocate a pool of buffers 
-     in the future */
-  hdr = (i3_header *)calloc(1, sizeof(i3_header));
-  if (hdr) 
-    return hdr;
-
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "FATAL ERROR: memory allocation 
error in alloc_i3_header\n");
-  return NULL;
-}
-
-
-/***************************************************************************
- *  init_i3_header - initialize i3 header data structure
- *
- *  input:
- *    hdr - header data structure to be initialized
- *    data - specifies whether the packet contains data payload
- *    stack - stack of IDs used to route the packet
- *    option_list - list of options 
- ***************************************************************************/
-
-void init_i3_header(i3_header *hdr, char data,
-                   i3_stack *stack, i3_option_list *option_list)
-{
-  hdr->ver = I3_v01;
-  hdr->flags = (data ? I3_DATA : 0);
-  hdr->stack = stack;
-  if (option_list) {
-    hdr->flags |= I3_OPTION_LIST;
-    hdr->option_list = option_list;
-  }
-}
-
-/***************************************************************************
- * duplicate_i3_header - duplicate the entire header
- **************************************************************************/
-i3_header *duplicate_i3_header(i3_header *h)
-{
-  i3_header *new_h;
-
-  new_h = alloc_i3_header();
-  new_h->ver = h->ver;
-  new_h->flags = h->flags;
-  new_h->stack = duplicate_i3_stack(h->stack);
-  new_h->option_list = duplicate_i3_option_list(h->option_list);
-
-  return new_h;
-}
-
-
-/***************************************************************************
- *  free_i3_header - free header data structure
- *
- *  input:
- *    header to be freed
- *
- ***************************************************************************/
-
-void free_i3_header(i3_header *hdr)
-{
-  if (hdr->stack)
-    free_i3_stack(hdr->stack);
-  if (hdr->option_list)
-    free_i3_option_list(hdr->option_list);
-  free(hdr);
-}
-
-
-/***************************************************************************
- *  pack_i3_header - convert a header data structure in packet format
- *
- *  input:
- *    p - address of the buffer where the header is to be stored in 
- *        packet format (pre-allocated)
- *    hdr - header to be converted in packet format
- *    
- *  output:
- *    length - length of the header in packet format (bytes)
- ***************************************************************************/
-
-void pack_i3_header(char *p, i3_header *hdr, unsigned short *length)
-{
-  unsigned short len;
-
-  *p = hdr->ver;
-  // printf("%d %d\n",p[0],*length);
-  
-  p += sizeof(char); *length = sizeof(char);
-  
-  *p = hdr->flags;
-  // printf("%d %d\n",p[0],*length);
-    
-  if (!hdr->option_list)
-    *p = *p & (~I3_OPTION_LIST); 
-  else
-    *p = *p | I3_OPTION_LIST;
-  p += sizeof(char); *length += sizeof(char);
-
-  *p = 0;
-  pack_i3_stack(p, hdr->stack, &len);
-  
-  *length += len; p += len;
-
-  if (hdr->option_list) {
-    pack_i3_option_list(p, hdr->option_list, &len);
-    *length += len;
-  }
-}
-
-
-unsigned short get_i3_header_len(i3_header *hdr)
-{
-  unsigned short length;
-
-  length = 2 * sizeof(char); /* version + flags*/ 
-
-  length += get_i3_stack_len(hdr->stack);
-
-  if (hdr->option_list) {
-      length += get_i3_option_list_len(hdr->option_list);
-  }
-
-  return length;
-}
-
-
-/***************************************************************************
- *  unpack_i3_header - allocate an i3_header data structure
- *                      and copy info from packet into it
- *
- *  input:
- *    p - address where header is stored in packet format
- *    
- *  output:
- *    length - length of the header info in packet format (bytes)
- *
- ***************************************************************************/
-
-i3_header *unpack_i3_header(char *p, unsigned short *length)
-{
-  unsigned short len;
-  i3_header *hdr = alloc_i3_header();
-
-  // printf("%d %d\n",p[0],*length);
-  hdr->ver = p[0];
-  p += sizeof(char); *length = sizeof(char);
-
-  //    printf("%d %d\n",p[0],*length);
-  hdr->flags = p[0]; 
-  p += sizeof(char); *length += sizeof(char);
-
-  // printf("%d %d\n",p[0],*length);
-  hdr->stack = unpack_i3_stack(p, &len);
-  p += len; *length += len;
-  // printf("%d %d\n",p[0],*length);
-   
-  if (hdr->flags & I3_OPTION_LIST) {
-    // printf("OPTIIONS: %d %d\n",p[0],*length);
-    hdr->option_list = unpack_i3_option_list(p, &len);
-    *length += len;
-    p += len;
-  }
-
-  return hdr;
-}
- 
-
-/***************************************************************************
- *  check_i3_header - check whether this is a legal header (should be
- *                    called when an i3 packet is received)
- *
- *  input:
- *    p - address where header is stored in packet format
- *
- *  return:
- *    error if any; FALSE otherwise
- *    
- ***************************************************************************/
-
-int check_i3_header(char *p, int pkt_len)
-{
-  unsigned short len;
-  int            rc;
-  char           flags;
-
-  /* check packet length */
-  if (pkt_len < 3) 
-    return I3_ERR_PKT_LEN_TOO_SHORT;
-
-  /* check version */
-  if (p[0] != I3_v01)
-    return I3_ERR_INVALID_VER;
-  p += sizeof(char); pkt_len -= sizeof(char); /* account for version */
-
-  /* check flags */
-  flags = p[0] & 0xf0;
-  if (flags & ~(I3_DATA | I3_OPTION_LIST | I3_FIRST_HOP))
-    return I3_ERR_INVALID_FLAGS;
-  p += sizeof(char); pkt_len -= sizeof(char); /* account for flags */
-
-  /* check ID stack */
-  if (*p > (char) I3_MAX_STACK_LEN) 
-    return I3_ERR_INVALID_STACK;
-  if ((rc = check_i3_stack(p, &len)) != FALSE)
-    return rc;
-  /* account for stack length */
-  p += len; pkt_len -= len;
-
-  /* check option list */
-  if (flags & I3_OPTION_LIST) {
-    if ((rc = check_i3_option_list(p, &len)) != FALSE)
-      return rc;
-  } else 
-    len = 0;
-
-  pkt_len -= len;
-  if (pkt_len < 0)
-    return I3_ERR_PKT_LEN_TOO_SHORT;
-
-  return 0;
-}
- 
-
-/***************************************************************************
- *  get_first_id - return the address of the first character
- *                 in the stack
- *
- *  input:
- *    p - i3 packet 
- *    
- *  return:
- *    pointer to the first ID in the stack
- *
- ***************************************************************************/
-
-char *get_first_id(char *p)
-{
-  /* stack follows after version and "flags" and "stack_length" fields */
-  return p + 3*sizeof(char);
-}
-
-/*********************
- ** print i3_header **
- *********************/
-
-void printf_i3_header(struct i3_header *hdr, int indent)
-{
-  char buf[INDENT_BUF_LEN];
-
-  memset(buf, ' ', indent);
-  buf[indent] = 0;
-
-  printf("%s header (version = %x, flags = %x (", 
-        buf, hdr->ver, hdr->flags);
-  if (hdr->flags & I3_DATA)
-    printf("I3_DATA| ");
-  if (hdr->flags & I3_OPTION_LIST)
-    printf("I3_OPTION_LIST| ");
-  if (hdr->flags & I3_FIRST_HOP)
-    printf("I3_FIRST_HOP| ");
-  if (hdr->flags & I3_TRIGGER_FLAG_ALLOW_SHORTCUT)
-    printf("I3_TRIGGER_FLAG_ALLOW_SHORTCUT | ");
-  printf(")\n");
-
-  printf_i3_stack(hdr->stack, indent + INDENT_CONST);
-  if (hdr->option_list)
-    printf_i3_option_list(hdr->option_list, indent + INDENT_CONST);
-
-  fflush(stdout);
-}
-
+/***************************************************************************
+*                         i3_header.c  -  description
+*                            -------------------
+*   begin                : Nov 27 2002
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#include "i3.h"
+#include "i3_fun.h"
+#include "i3_debug.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/***************************************************************************
+*  alloc_i3_header - allocate i3 header data structure
+*
+*  return:
+*    pointer to the allocated data structure
+***************************************************************************/
+
+i3_header *alloc_i3_header()
+{
+    struct i3_header *hdr;
+
+    /* XXX: just simply call alloc for now; preallocate a pool of buffers
+     * in the future */
+    hdr = (i3_header *) calloc(1, sizeof(i3_header));
+    if (hdr) {
+        return hdr;
+    }
+
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "FATAL ERROR: memory allocation 
error in alloc_i3_header\n");
+    return NULL;
+}
+
+/***************************************************************************
+*  init_i3_header - initialize i3 header data structure
+*
+*  input:
+*    hdr - header data structure to be initialized
+*    data - specifies whether the packet contains data payload
+*    stack - stack of IDs used to route the packet
+*    option_list - list of options
+***************************************************************************/
+
+void init_i3_header(i3_header *hdr, char data,
+                    i3_stack *stack, i3_option_list *option_list)
+{
+    hdr->ver   = I3_v01;
+    hdr->flags = (data ? I3_DATA : 0);
+    hdr->stack = stack;
+    if (option_list) {
+        hdr->flags      |= I3_OPTION_LIST;
+        hdr->option_list = option_list;
+    }
+}
+
+/***************************************************************************
+ * duplicate_i3_header - duplicate the entire header
+ **************************************************************************/
+i3_header *duplicate_i3_header(i3_header *h)
+{
+    i3_header *new_h;
+
+    new_h              = alloc_i3_header();
+    new_h->ver         = h->ver;
+    new_h->flags       = h->flags;
+    new_h->stack       = duplicate_i3_stack(h->stack);
+    new_h->option_list = duplicate_i3_option_list(h->option_list);
+
+    return new_h;
+}
+
+/***************************************************************************
+*  free_i3_header - free header data structure
+*
+*  input:
+*    header to be freed
+*
+***************************************************************************/
+
+void free_i3_header(i3_header *hdr)
+{
+    if (hdr->stack) {
+        free_i3_stack(hdr->stack);
+    }
+    if (hdr->option_list) {
+        free_i3_option_list(hdr->option_list);
+    }
+    free(hdr);
+}
+
+/***************************************************************************
+*  pack_i3_header - convert a header data structure in packet format
+*
+*  input:
+*    p - address of the buffer where the header is to be stored in
+*        packet format (pre-allocated)
+*    hdr - header to be converted in packet format
+*
+*  output:
+*    length - length of the header in packet format (bytes)
+***************************************************************************/
+
+void pack_i3_header(char *p, i3_header *hdr, unsigned short *length)
+{
+    unsigned short len;
+
+    *p      = hdr->ver;
+    // printf("%d %d\n",p[0],*length);
+
+    p      += sizeof(char);
+    *length = sizeof(char);
+
+    *p      = hdr->flags;
+    // printf("%d %d\n",p[0],*length);
+
+    if (!hdr->option_list) {
+        *p = *p & (~I3_OPTION_LIST);
+    } else {
+        *p = *p | I3_OPTION_LIST;
+    }
+    p       += sizeof(char);
+    *length += sizeof(char);
+
+    *p       = 0;
+    pack_i3_stack(p, hdr->stack, &len);
+
+    *length += len;
+    p       += len;
+
+    if (hdr->option_list) {
+        pack_i3_option_list(p, hdr->option_list, &len);
+        *length += len;
+    }
+}
+
+unsigned short get_i3_header_len(i3_header *hdr)
+{
+    unsigned short length;
+
+    length  = 2 * sizeof(char); /* version + flags*/
+
+    length += get_i3_stack_len(hdr->stack);
+
+    if (hdr->option_list) {
+        length += get_i3_option_list_len(hdr->option_list);
+    }
+
+    return length;
+}
+
+/***************************************************************************
+*  unpack_i3_header - allocate an i3_header data structure
+*                      and copy info from packet into it
+*
+*  input:
+*    p - address where header is stored in packet format
+*
+*  output:
+*    length - length of the header info in packet format (bytes)
+*
+***************************************************************************/
+
+i3_header *unpack_i3_header(char *p, unsigned short *length)
+{
+    unsigned short len;
+    i3_header *hdr = alloc_i3_header();
+
+    // printf("%d %d\n",p[0],*length);
+    hdr->ver   = p[0];
+    p         += sizeof(char);
+    *length    = sizeof(char);
+
+    //    printf("%d %d\n",p[0],*length);
+    hdr->flags = p[0];
+    p         += sizeof(char);
+    *length   += sizeof(char);
+
+    // printf("%d %d\n",p[0],*length);
+    hdr->stack = unpack_i3_stack(p, &len);
+    p         += len;
+    *length   += len;
+    // printf("%d %d\n",p[0],*length);
+
+    if (hdr->flags & I3_OPTION_LIST) {
+        // printf("OPTIIONS: %d %d\n",p[0],*length);
+        hdr->option_list = unpack_i3_option_list(p, &len);
+        *length         += len;
+        p               += len;
+    }
+
+    return hdr;
+}
+
+/***************************************************************************
+*  check_i3_header - check whether this is a legal header (should be
+*                    called when an i3 packet is received)
+*
+*  input:
+*    p - address where header is stored in packet format
+*
+*  return:
+*    error if any; FALSE otherwise
+*
+***************************************************************************/
+
+int check_i3_header(char *p, int pkt_len)
+{
+    unsigned short len;
+    int rc;
+    char flags;
+
+    /* check packet length */
+    if (pkt_len < 3) {
+        return I3_ERR_PKT_LEN_TOO_SHORT;
+    }
+
+    /* check version */
+    if (p[0] != I3_v01) {
+        return I3_ERR_INVALID_VER;
+    }
+    p       += sizeof(char);
+    pkt_len -= sizeof(char);                  /* account for version */
+
+    /* check flags */
+    flags    = p[0] & 0xf0;
+    if (flags & ~(I3_DATA | I3_OPTION_LIST | I3_FIRST_HOP)) {
+        return I3_ERR_INVALID_FLAGS;
+    }
+    p       += sizeof(char);
+    pkt_len -= sizeof(char);                  /* account for flags */
+
+    /* check ID stack */
+    if (*p > (char) I3_MAX_STACK_LEN) {
+        return I3_ERR_INVALID_STACK;
+    }
+    if ((rc = check_i3_stack(p, &len)) != FALSE) {
+        return rc;
+    }
+    /* account for stack length */
+    p       += len;
+    pkt_len -= len;
+
+    /* check option list */
+    if (flags & I3_OPTION_LIST) {
+        if ((rc = check_i3_option_list(p, &len)) != FALSE) {
+            return rc;
+        }
+    } else {
+        len = 0;
+    }
+
+    pkt_len -= len;
+    if (pkt_len < 0) {
+        return I3_ERR_PKT_LEN_TOO_SHORT;
+    }
+
+    return 0;
+}
+
+/***************************************************************************
+*  get_first_id - return the address of the first character
+*                 in the stack
+*
+*  input:
+*    p - i3 packet
+*
+*  return:
+*    pointer to the first ID in the stack
+*
+***************************************************************************/
+
+char *get_first_id(char *p)
+{
+    /* stack follows after version and "flags" and "stack_length" fields */
+    return p + 3 * sizeof(char);
+}
+
+/*********************
+** print i3_header **
+*********************/
+
+void printf_i3_header(struct i3_header *hdr, int indent)
+{
+    char buf[INDENT_BUF_LEN];
+
+    memset(buf, ' ', indent);
+    buf[indent] = 0;
+
+    printf("%s header (version = %x, flags = %x (",
+           buf, hdr->ver, hdr->flags);
+    if (hdr->flags & I3_DATA) {
+        printf("I3_DATA| ");
+    }
+    if (hdr->flags & I3_OPTION_LIST) {
+        printf("I3_OPTION_LIST| ");
+    }
+    if (hdr->flags & I3_FIRST_HOP) {
+        printf("I3_FIRST_HOP| ");
+    }
+    if (hdr->flags & I3_TRIGGER_FLAG_ALLOW_SHORTCUT) {
+        printf("I3_TRIGGER_FLAG_ALLOW_SHORTCUT | ");
+    }
+    printf(")\n");
+
+    printf_i3_stack(hdr->stack, indent + INDENT_CONST);
+    if (hdr->option_list) {
+        printf_i3_option_list(hdr->option_list, indent + INDENT_CONST);
+    }
+
+    fflush(stdout);
+}

=== modified file 'i3/i3/i3_header.h'
--- i3/i3/i3_header.h   2010-01-06 22:17:32 +0000
+++ i3/i3/i3_header.h   2010-02-11 11:49:47 +0000
@@ -1,27 +1,27 @@
-/***************************************************************************
-                          i3_header.h  -  description
-                             -------------------
-    begin                : Fre Jun 20 2003
-    copyright            : (C) 2003 by klaus
-    email                : wehrle@xxxxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef I3_HEADER_H
-#define I3_HEADER_H
-
- 
-/* functions implemented in i3_header.c */
-i3_header *alloc_i3_header(void);
-void init_i3_header(i3_header *hdr, char data,
-                   i3_stack *stack, i3_option_list *option_list);
-i3_header *duplicate_i3_header(i3_header *h);
-void free_i3_header(i3_header *hdr);
-void pack_i3_header(char *packedhdr, i3_header *hdr,
-                   unsigned short *length);
-unsigned short get_i3_header_len(i3_header *hdr);
-i3_header *unpack_i3_header(char *packedhdr, unsigned short *length);
-int check_i3_header(char *p, int pkt_len);
-char *get_first_id(char *packet);
-void printf_i3_header(struct i3_header *hdr, int indent);
-
-#endif
+/***************************************************************************
+*                         i3_header.h  -  description
+*                            -------------------
+*   begin                : Fre Jun 20 2003
+*   copyright            : (C) 2003 by klaus
+*   email                : wehrle@xxxxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef I3_HEADER_H
+#define I3_HEADER_H
+
+
+/* functions implemented in i3_header.c */
+i3_header *alloc_i3_header(void);
+void init_i3_header(i3_header *hdr, char data,
+                    i3_stack *stack, i3_option_list *option_list);
+i3_header *duplicate_i3_header(i3_header *h);
+void free_i3_header(i3_header *hdr);
+void pack_i3_header(char *packedhdr, i3_header *hdr,
+                    unsigned short *length);
+unsigned short get_i3_header_len(i3_header *hdr);
+i3_header *unpack_i3_header(char *packedhdr, unsigned short *length);
+int check_i3_header(char *p, int pkt_len);
+char *get_first_id(char *packet);
+void printf_i3_header(struct i3_header *hdr, int indent);
+
+#endif

=== modified file 'i3/i3/i3_id.c'
--- i3/i3/i3_id.c       2009-12-11 22:49:11 +0000
+++ i3/i3/i3_id.c       2010-02-11 11:49:47 +0000
@@ -1,337 +1,333 @@
-/***************************************************************************
-                          i3_id.c  -  description
-                             -------------------
-    begin                : Nov 20 2002
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#include "i3.h"
-#include "i3_fun.h"
-#include "i3_debug.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-/***************************************************************************
- *  alloc_i3_id - allocate a indientifie data structure
- *
- *  return:
- *    allocated identifier 
- ***************************************************************************/
-
-ID *alloc_i3_id()
-{
-  ID *id;
-
-  if ((id = (ID *)malloc(sizeof(ID))) == NULL)
-        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "alloc_i3_id: memory 
allocation error.\n");
-  return id;
-}
-
-
-/***************************************************************************
- *  init_i3_id - initialized identifier
- *
- *  input
- *    id, id1 - set id to id1
- *    
- ***************************************************************************/
-
-void init_i3_id(ID *id, const ID *id1)
-{
-  memcpy(id->x, id1->x, sizeof(ID));
-}
-
-
-/***************************************************************************
- *  free_i3_id - free identifier
- *
- *  input:
- *    id to be freed
- ***************************************************************************/
-
-void free_i3_id(ID *id)
-{
-  free(id);
-}
-
-
-/***************************************************************************
- *  duplicate_i3_id - create a replica of identifier id
- *
- *  input:
- *    id - identifier to be duplicated
- *
- *  return:
- *    replica of id
- ***************************************************************************/
-
-ID *duplicate_i3_id(ID *id)
-{
-  ID *idnew = alloc_i3_id();
-
-  init_i3_id(idnew, id);
-  return idnew;
-}
-
-/***************************************************************************
- *  pack_i3_id - convert identifier in packet format
- *
- *  input:
- *    p - address of the buffer where the id is to be stored in 
- *        packet format (the buffer is pre-allocated)
- *    id - id to be converted in packet format
- *    
- *  output:
- *    length - length of the identifier in packet format
- ***************************************************************************/
-
-void pack_i3_id(char *p, ID *id, unsigned short *length)
-{
-  memcpy(p, id->x, sizeof(ID));
-  *length = sizeof(ID);
-}
-
-
-
-/***************************************************************************
- *  unpack_i3_id - copy identifier info from packet to an identifier 
- *                 data structure 
- *
- *  input:
- *    p - address where identifier is stored in packet format
- *   
- *  return:
- *    id - identifier data structure
- * 
- *  output:
- *    length - length of the id info in packet format
- *
- ***************************************************************************/
-
-ID *unpack_i3_id(char *p, unsigned short *length)
-{
-  ID *id = alloc_i3_id();
- 
-  memcpy(id->x, p, sizeof(ID));
-  *length = sizeof(ID);
-
-  return id;
-}
-
-// Assume: s has enough space
-/**
-  * This function prints the ID specified by <code>id</code>
-  * in the character pointed to by <code>s</code>.
-  * It is assumed that enough space has already been allocated
-  * for the character array.
-  * @param s  the character array into which the id should be printed.
-  * @param id the ID to be printed.
-  * @return Returns the same pointer as that passed in parameter 
<code>s</code>.  
-  * This is useful when you want to use sprintf_i3_id as part of some other 
-  * printf statement.
-  */
-char* sprintf_i3_id(char* s, const ID *id)
-{
-   uint i; 
-
-   *s = 0;
-   for (i = 0; i < sizeof(ID); i++)
-   {
-     char ts[20];
-     sprintf(ts, "%02x", (int)(id->x[i]));
-     strcat(s,ts);
-   }
-
-   return s;
-}
-
-/**
- * This function can read back the ID from the 
- * string printed by sprintf_i3_id.
- */
-ID* sscanf_i3_id(char *id_str, ID* id) {
-  uint i;
-  int c;
-  for (i = 0; i < sizeof(ID); i++) {
-    sscanf(id_str, "%02x", &c);
-    id->x[i] = (uint8_t)c;
-    id_str += 2;
-  }
-  return id;
-}
-
-char* sprintf_i3_key(char* s, const Key *key)
-{
-   uint i; 
-
-   *s = 0;
-   for (i = 0; i < sizeof(Key); i++)
-   {
-     char ts[20];
-     sprintf(ts, "%02x", (int)(key->x[i]));
-     strcat(s,ts);
-   }
-
-   return s;
-}
-
-
-/**
- * This function can read back the Key from the 
- * string printed by sprintf_i3_key.
- */
-Key* sscanf_i3_key(char *id_str, Key *key) {
-  uint i; 
-  int c;
-  for (i = 0; i < sizeof(Key); i++) {
-    sscanf(id_str, "%02x", &c);
-    key->x[i] = (uint8_t) c;
-    id_str += 2;
-  }
-
-  return key;
-}
-/*************************************
- ** print i3_id; just for test   **
- *************************************/
-
-void fprintf_i3_id(FILE *fp, ID *id, int indent)
-{
-   char buf[INDENT_BUF_LEN];
-   uint i;
-
-  memset(buf, ' ', INDENT_BUF_LEN);
-  buf[indent] = 0;
-
-  fprintf(fp, "%s id: ", buf);
-  for (i = 0; i < sizeof(ID); i++)
-    fprintf(fp, "%02x", (int)(id->x[i])); 
-  fprintf(fp, "\n");
-}
-
-void printf_i3_id(ID *id, int indent)
-{
-   char buf[INDENT_BUF_LEN];
-   uint i;
-
-  memset(buf, ' ', INDENT_BUF_LEN);
-  buf[indent] = 0;
-
-  printf("%s id: ", buf);
-  for (i = 0; i < sizeof(ID); i++)
-    printf("%02x", (int)(id->x[i])); 
-  printf("\n");
-}
-
-/************************************************************************
- * Compare two ids and return an integer less than, equal  to, or
- * greater than zero if id1 is found, respectively, to be less than,
- * to match, or be greater than s2.
- ***********************************************************************/
-int compare_ids(ID *id1, ID *id2)
-{
-    assert(NULL != id1 && NULL != id2);
-    return memcmp(id1->x, id2->x, ID_LEN);
-}
-
-/************************************************************************
- * Purpose: Convert a string to i3 id eg. read from file
- * XXX Check where this should be included ... may be in some other
- * file -- To check for bugs also
- ***********************************************************************/
-static unsigned char todigit(char ch)
-{
-    if (isdigit((int) ch))
-       return (ch - '0');
-    else
-       return (10 + ch - 'a');
-}
-
-ID atoi3id(char *str)
-{
-    ID id;
-    int i, len;
-    
-       len = (int) strlen(str);
-       assert(len <= 2*ID_LEN);
-    memset(id.x, 0, ID_LEN);
-    
-    if (len % 2 != 0) {
-       str[len] = '0';
-       len++;
-    }
-    
-    for (i = 0; i < len/2; i++)
-       id.x[ i ] = (todigit(str[2*i]) << 4) | todigit(str[2*i+1]);
-
-    str[len--] = 0;    // to restore old str
-    return id;
-}
-
-/************************************************************************
- * Purpose:  Public ID constraint
- *     Public IDs (ie. IDs that need to be protected from
- *     impersonation) need to have "public_id" bit set. The public_id
- *     bit is the last bit in the prefix.
- ***********************************************************************/
-void set_id_type(ID *id,  char type)
-{
-    uint8_t mask = 1;
-
-    if (I3_ID_TYPE_PUBLIC == type) {
-       
-        // last two bits 01 if UNCONSTRAINED type exists
-        id->x[PREFIX_LEN-1] |= mask;
-        //id->x[PREFIX_LEN - 2] &= ~mask;
-        
-    } else if (I3_ID_TYPE_PRIVATE == type) {
-            
-        // last two bits 00 if UNCONSTRAINED ID type exists
-        id->x[PREFIX_LEN-1] &= ~mask;
-        //id->x[PREFIX_LEN - 2] &= ~mask;
-   
-    /**
-    } else if (I3_ID_TYPE_UNCONSTRAINED == type) {
-        
-        // last two bits 10
-        id->x[PREFIX_LEN - 2] |= mask;
-        id->x[PREFIX_LEN - 1] &= ~mask;
-    */
-        
-    } else {
-           I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "set_id_type: Unknown type: 
%d\n", type);
-    }
-}
-
-char get_id_type(ID *id)
-{
-    uint8_t mask = 1;
-
-    /* Only if UNCONSTRAINED id type exists
-    if ((id->x[PREFIX_LEN - 2] & mask) == 1) {
-        //second last bit 1
-        if ((id->x[PREFIX_LEN - 1] & mask) == 1) {
-            //last bit 1
-            return I3_ID_TYPE_UNKNOWN;
-        } else {
-            // last bit 0
-            return I3_ID_TYPE_UNCONSTRAINED;
-        }
-    } else {
-        //second last bit 0
-
-    */
-        if ((id->x[PREFIX_LEN-1] & mask) == 1) {
-            //last bit 1
-               return I3_ID_TYPE_PUBLIC;
-        } else {
-            //last bit 0
-               return I3_ID_TYPE_PRIVATE;
-        }
-
-    /* Only if UNCONSTRAINED id type exists
-       }
-    */
-}
+/***************************************************************************
+*                         i3_id.c  -  description
+*                            -------------------
+*   begin                : Nov 20 2002
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#include "i3.h"
+#include "i3_fun.h"
+#include "i3_debug.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+/***************************************************************************
+*  alloc_i3_id - allocate a indientifie data structure
+*
+*  return:
+*    allocated identifier
+***************************************************************************/
+
+ID *alloc_i3_id()
+{
+    ID *id;
+
+    if ((id = (ID *) malloc(sizeof(ID))) == NULL) {
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "alloc_i3_id: memory 
allocation error.\n");
+    }
+    return id;
+}
+
+/***************************************************************************
+*  init_i3_id - initialized identifier
+*
+*  input
+*    id, id1 - set id to id1
+*
+***************************************************************************/
+
+void init_i3_id(ID *id, const ID *id1)
+{
+    memcpy(id->x, id1->x, sizeof(ID));
+}
+
+/***************************************************************************
+*  free_i3_id - free identifier
+*
+*  input:
+*    id to be freed
+***************************************************************************/
+
+void free_i3_id(ID *id)
+{
+    free(id);
+}
+
+/***************************************************************************
+*  duplicate_i3_id - create a replica of identifier id
+*
+*  input:
+*    id - identifier to be duplicated
+*
+*  return:
+*    replica of id
+***************************************************************************/
+
+ID *duplicate_i3_id(ID *id)
+{
+    ID *idnew = alloc_i3_id();
+
+    init_i3_id(idnew, id);
+    return idnew;
+}
+
+/***************************************************************************
+*  pack_i3_id - convert identifier in packet format
+*
+*  input:
+*    p - address of the buffer where the id is to be stored in
+*        packet format (the buffer is pre-allocated)
+*    id - id to be converted in packet format
+*
+*  output:
+*    length - length of the identifier in packet format
+***************************************************************************/
+
+void pack_i3_id(char *p, ID *id, unsigned short *length)
+{
+    memcpy(p, id->x, sizeof(ID));
+    *length = sizeof(ID);
+}
+
+/***************************************************************************
+*  unpack_i3_id - copy identifier info from packet to an identifier
+*                 data structure
+*
+*  input:
+*    p - address where identifier is stored in packet format
+*
+*  return:
+*    id - identifier data structure
+*
+*  output:
+*    length - length of the id info in packet format
+*
+***************************************************************************/
+
+ID *unpack_i3_id(char *p, unsigned short *length)
+{
+    ID *id = alloc_i3_id();
+
+    memcpy(id->x, p, sizeof(ID));
+    *length = sizeof(ID);
+
+    return id;
+}
+
+// Assume: s has enough space
+/**
+ * This function prints the ID specified by <code>id</code>
+ * in the character pointed to by <code>s</code>.
+ * It is assumed that enough space has already been allocated
+ * for the character array.
+ * @param s  the character array into which the id should be printed.
+ * @param id the ID to be printed.
+ * @return Returns the same pointer as that passed in parameter <code>s</code>.
+ * This is useful when you want to use sprintf_i3_id as part of some other
+ * printf statement.
+ */
+char *sprintf_i3_id(char *s, const ID *id)
+{
+    uint i;
+
+    *s = 0;
+    for (i = 0; i < sizeof(ID); i++) {
+        char ts[20];
+        sprintf(ts, "%02x", (int) (id->x[i]));
+        strcat(s, ts);
+    }
+
+    return s;
+}
+
+/**
+ * This function can read back the ID from the
+ * string printed by sprintf_i3_id.
+ */
+ID *sscanf_i3_id(char *id_str, ID *id)
+{
+    uint i;
+    int c;
+    for (i = 0; i < sizeof(ID); i++) {
+        sscanf(id_str, "%02x", &c);
+        id->x[i] = (uint8_t) c;
+        id_str  += 2;
+    }
+    return id;
+}
+
+char *sprintf_i3_key(char *s, const Key *key)
+{
+    uint i;
+
+    *s = 0;
+    for (i = 0; i < sizeof(Key); i++) {
+        char ts[20];
+        sprintf(ts, "%02x", (int) (key->x[i]));
+        strcat(s, ts);
+    }
+
+    return s;
+}
+
+/**
+ * This function can read back the Key from the
+ * string printed by sprintf_i3_key.
+ */
+Key *sscanf_i3_key(char *id_str, Key *key)
+{
+    uint i;
+    int c;
+    for (i = 0; i < sizeof(Key); i++) {
+        sscanf(id_str, "%02x", &c);
+        key->x[i] = (uint8_t) c;
+        id_str   += 2;
+    }
+
+    return key;
+}
+
+/*************************************
+** print i3_id; just for test   **
+*************************************/
+
+void fprintf_i3_id(FILE *fp, ID *id, int indent)
+{
+    char buf[INDENT_BUF_LEN];
+    uint i;
+
+    memset(buf, ' ', INDENT_BUF_LEN);
+    buf[indent] = 0;
+
+    fprintf(fp, "%s id: ", buf);
+    for (i = 0; i < sizeof(ID); i++) {
+        fprintf(fp, "%02x", (int) (id->x[i]));
+    }
+    fprintf(fp, "\n");
+}
+
+void printf_i3_id(ID *id, int indent)
+{
+    char buf[INDENT_BUF_LEN];
+    uint i;
+
+    memset(buf, ' ', INDENT_BUF_LEN);
+    buf[indent] = 0;
+
+    printf("%s id: ", buf);
+    for (i = 0; i < sizeof(ID); i++) {
+        printf("%02x", (int) (id->x[i]));
+    }
+    printf("\n");
+}
+
+/************************************************************************
+ * Compare two ids and return an integer less than, equal  to, or
+ * greater than zero if id1 is found, respectively, to be less than,
+ * to match, or be greater than s2.
+ ***********************************************************************/
+int compare_ids(ID *id1, ID *id2)
+{
+    assert(NULL != id1 && NULL != id2);
+    return memcmp(id1->x, id2->x, ID_LEN);
+}
+
+/************************************************************************
+ * Purpose: Convert a string to i3 id eg. read from file
+ * XXX Check where this should be included ... may be in some other
+ * file -- To check for bugs also
+ ***********************************************************************/
+static unsigned char todigit(char ch)
+{
+    if (isdigit((int) ch)) {
+        return ch - '0';
+    } else {
+        return 10 + ch - 'a';
+    }
+}
+
+ID atoi3id(char *str)
+{
+    ID id;
+    int i, len;
+
+    len = (int) strlen(str);
+    assert(len <= 2 * ID_LEN);
+    memset(id.x, 0, ID_LEN);
+
+    if (len % 2 != 0) {
+        str[len] = '0';
+        len++;
+    }
+
+    for (i = 0; i < len / 2; i++) {
+        id.x[ i ] = (todigit(str[2 * i]) << 4) | todigit(str[2 * i + 1]);
+    }
+
+    str[len--] = 0;     // to restore old str
+    return id;
+}
+
+/************************************************************************
+ * Purpose:  Public ID constraint
+ *  Public IDs (ie. IDs that need to be protected from
+ *  impersonation) need to have "public_id" bit set. The public_id
+ *  bit is the last bit in the prefix.
+ ***********************************************************************/
+void set_id_type(ID *id,  char type)
+{
+    uint8_t mask = 1;
+
+    if (I3_ID_TYPE_PUBLIC == type) {
+        // last two bits 01 if UNCONSTRAINED type exists
+        id->x[PREFIX_LEN - 1] |= mask;
+        //id->x[PREFIX_LEN - 2] &= ~mask;
+    } else if (I3_ID_TYPE_PRIVATE == type) {
+        // last two bits 00 if UNCONSTRAINED ID type exists
+        id->x[PREFIX_LEN - 1] &= ~mask;
+        //id->x[PREFIX_LEN - 2] &= ~mask;
+
+        /**
+         * } else if (I3_ID_TYPE_UNCONSTRAINED == type) {
+         *
+         *  // last two bits 10
+         *  id->x[PREFIX_LEN - 2] |= mask;
+         *  id->x[PREFIX_LEN - 1] &= ~mask;
+         */
+    } else {
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "set_id_type: Unknown type: 
%d\n", type);
+    }
+}
+
+char get_id_type(ID *id)
+{
+    uint8_t mask = 1;
+
+    /* Only if UNCONSTRAINED id type exists
+     * if ((id->x[PREFIX_LEN - 2] & mask) == 1) {
+     *  //second last bit 1
+     *  if ((id->x[PREFIX_LEN - 1] & mask) == 1) {
+     *      //last bit 1
+     *      return I3_ID_TYPE_UNKNOWN;
+     *  } else {
+     *      // last bit 0
+     *      return I3_ID_TYPE_UNCONSTRAINED;
+     *  }
+     * } else {
+     *  //second last bit 0
+     *
+     */
+    if ((id->x[PREFIX_LEN - 1] & mask) == 1) {
+        //last bit 1
+        return I3_ID_TYPE_PUBLIC;
+    } else {
+        //last bit 0
+        return I3_ID_TYPE_PRIVATE;
+    }
+
+    /* Only if UNCONSTRAINED id type exists
+     * }
+     */
+}

=== modified file 'i3/i3/i3_id.h'
--- i3/i3/i3_id.h       2010-01-06 22:17:32 +0000
+++ i3/i3/i3_id.h       2010-02-11 11:49:47 +0000
@@ -1,39 +1,39 @@
-/***************************************************************************
-                          i3_id.h  -  description
-                             -------------------
-    begin                : Fre Jun 20 2003
-    copyright            : (C) 2003 by Ion
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef I3_ID_H
-#define I3_ID_H
- 
-#include <stdio.h>
-#include "i3.h"
-
-/* functions implemented in i3_id.c */
-ID *alloc_i3_id(void);
-void init_i3_id(ID *id, const ID *id1);
-void free_i3_id(ID *id);
-void pack_i3_id(char *packedid, ID *id, unsigned short *length);
-ID *unpack_i3_id(char *p, unsigned short *length);
-void printf_i3_id(ID *id, int intend);
-void fprintf_i3_id(FILE *fp, ID *id, int intend);
-
-char* sprintf_i3_id(char* s, const ID *id);
-char* sprintf_i3_key(char* s, const Key *key);
-ID* sscanf_i3_id(char *s, ID *id);
-Key* sscanf_i3_key(char *s, Key *key);
-
-ID *duplicate_i3_id(ID *id);
-int compare_ids(ID *id1, ID *id2);
-ID atoi3id(char *str);
-
-/* for public ID constraints */
-char get_id_type(ID *id);
-void set_id_type(ID *id,  char type);
-#define set_public_id(id) set_id_type(id, I3_ID_TYPE_PUBLIC)
-#define set_private_id(id) set_id_type(id, I3_ID_TYPE_PRIVATE)
-
-#endif
+/***************************************************************************
+*                         i3_id.h  -  description
+*                            -------------------
+*   begin                : Fre Jun 20 2003
+*   copyright            : (C) 2003 by Ion
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef I3_ID_H
+#define I3_ID_H
+
+#include <stdio.h>
+#include "i3.h"
+
+/* functions implemented in i3_id.c */
+ID *alloc_i3_id(void);
+void init_i3_id(ID *id, const ID *id1);
+void free_i3_id(ID *id);
+void pack_i3_id(char *packedid, ID *id, unsigned short *length);
+ID *unpack_i3_id(char *p, unsigned short *length);
+void printf_i3_id(ID *id, int intend);
+void fprintf_i3_id(FILE *fp, ID *id, int intend);
+
+char *sprintf_i3_id(char *s, const ID *id);
+char *sprintf_i3_key(char *s, const Key *key);
+ID *sscanf_i3_id(char *s, ID *id);
+Key *sscanf_i3_key(char *s, Key *key);
+
+ID *duplicate_i3_id(ID *id);
+int compare_ids(ID *id1, ID *id2);
+ID atoi3id(char *str);
+
+/* for public ID constraints */
+char get_id_type(ID *id);
+void set_id_type(ID *id,  char type);
+#define set_public_id(id) set_id_type(id, I3_ID_TYPE_PUBLIC)
+#define set_private_id(id) set_id_type(id, I3_ID_TYPE_PRIVATE)
+
+#endif

=== modified file 'i3/i3/i3_misc.c'
--- i3/i3/i3_misc.c     2009-12-11 22:49:11 +0000
+++ i3/i3/i3_misc.c     2010-02-11 11:49:47 +0000
@@ -1,31 +1,32 @@
-/***************************************************************************
-                          i3_misc.c  -  description
-                             -------------------
-    begin                : Nov 20 2002
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <errno.h>
-
-void panic(char *fmt, ...)
-{
-    va_list args;
-    
-    fflush(stdout);
-    fprintf(stderr, "FATAL ERROR: ");
-    
-    va_start(args, fmt);
-    vfprintf(stderr, fmt, args);
-    va_end(args);
-    
-    if (fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':')
-       fprintf(stderr, " %s", strerror(errno));
-    fprintf(stderr, "\n");
-                                                                               
-    exit(2); /* conventional value for failed execution */
-}
+/***************************************************************************
+*                         i3_misc.c  -  description
+*                            -------------------
+*   begin                : Nov 20 2002
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+
+void panic(char *fmt, ...)
+{
+    va_list args;
+
+    fflush(stdout);
+    fprintf(stderr, "FATAL ERROR: ");
+
+    va_start(args, fmt);
+    vfprintf(stderr, fmt, args);
+    va_end(args);
+
+    if (fmt[0] != '\0' && fmt[strlen(fmt) - 1] == ':') {
+        fprintf(stderr, " %s", strerror(errno));
+    }
+    fprintf(stderr, "\n");
+
+    exit(2); /* conventional value for failed execution */
+}

=== modified file 'i3/i3/i3_misc.h'
--- i3/i3/i3_misc.h     2009-12-11 22:49:11 +0000
+++ i3/i3/i3_misc.h     2010-02-11 11:49:47 +0000
@@ -1,15 +1,15 @@
-/***************************************************************************
-                          i3_misc.h  -  description
-                             -------------------
-    begin                : Fre Jun 20 2003
-    copyright            : (C) 2003 by klaus
-    email                : wehrle@xxxxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef I3_MISC_H
-#define I3_MISC_H
-
-/* functions implemented in i3_misc.c */
-void panic(char *fmt, ...);
-
-#endif
+/***************************************************************************
+*                         i3_misc.h  -  description
+*                            -------------------
+*   begin                : Fre Jun 20 2003
+*   copyright            : (C) 2003 by klaus
+*   email                : wehrle@xxxxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef I3_MISC_H
+#define I3_MISC_H
+
+/* functions implemented in i3_misc.c */
+void panic(char *fmt, ...);
+
+#endif

=== modified file 'i3/i3/i3_options.c'
--- i3/i3/i3_options.c  2009-12-11 22:49:11 +0000
+++ i3/i3/i3_options.c  2010-02-11 11:49:47 +0000
@@ -1,863 +1,867 @@
-/***************************************************************************
-                          i3_options.c  -  description
-                             -------------------
-    begin                : Nov 21 2002
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#include "i3.h"
-#include "i3_fun.h"
-#include "i3_debug.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-
-/***************************************************************************
- *  alloc_i3_option - allocate i3 option data structure
- *
- *  return:
- *    pointer to the allocated data structure 
- ***************************************************************************/
-struct i3_option *alloc_i3_option()
-{
-  struct i3_option *option;
-
-   option = (i3_option *)calloc(1, sizeof(i3_option));
-   if (option) 
-      return option;
-
-   I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,"FATAL ERROR: memory allocation 
error in alloc_i3_option\n");
-   return NULL;
-}
-
-
-/***************************************************************************
- *  init_i3_option - initialize i3 option data structure
- *
- *  input:
- *    option - data structure to be initialized
- *    type - option type
- *    entry - option entry, e.g., ret_addr, trigger (pre-allocated)
- *
- ***************************************************************************/
-void init_i3_option(i3_option *option, char type, void * __RTTI entry)
-{
-  option->type = type;
-  /* all are pointers; just use one type for assigment */
-  if (type == I3_OPT_REQUEST_FOR_CACHE 
-      || type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT
-      || type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR 
-#if NEWS_INSTRUMENT
-      || type == I3_OPT_LOG_PACKET || type == I3_OPT_APPEND_TS
-#endif
-      )
-    option->entry.nothing = (void *)NULL;
-  else
-    option->entry.trigger = (i3_trigger *)entry;
-}
-
-static void * __RTTI duplicate_i3_option_entry(char type, void * __RTTI entry)
-{
-  if (NULL == entry)
-    return NULL;
-
-  if (I3_OPT_SENDER == type || I3_OPT_DESTINATION == type)
-    return duplicate_i3_addr((i3_addr *) entry);
-  else if (I3_OPT_TRIGGER_INSERT == type ||
-          I3_OPT_TRIGGER_CHALLENGE == type ||
-          I3_OPT_CONSTRAINT_FAILED == type ||
-          I3_OPT_TRIGGER_ACK == type ||
-          I3_OPT_TRIGGER_REMOVE == type ||
-          I3_OPT_CACHE_ADDR == type ||
-          I3_OPT_CACHE_DEST_ADDR == type ||
-          I3_OPT_CACHE_SHORTCUT_ADDR == type ||
-          I3_OPT_FORCE_CACHE_ADDR == type ||
-          I3_OPT_ROUTE_BROKEN == type)
-    return duplicate_i3_trigger((i3_trigger *) entry);
-  else if (I3_OPT_TRIGGER_NOT_PRESENT == type ||
-          I3_OPT_TRIGGER_RATELIMIT == type)
-    return duplicate_i3_id((ID *) entry);
-  else {
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "duplicate_i3_option: invalid 
option type\n");
-    return NULL;
-  }
-}
-
-i3_option *duplicate_i3_option(i3_option *option)
-{
-    i3_option *new_option = alloc_i3_option();
-    
-    new_option->type = option->type;
-    new_option->entry.trigger = (i3_trigger *)
-       duplicate_i3_option_entry(option->type, (void *)option->entry.trigger);
-    
-    return new_option;
-}
-
-/***************************************************************************
- *  free_i3_option - free option data structure
- *
- *  input:
- *    data structure to be freed
- *
- ***************************************************************************/
-void free_i3_option(i3_option *option)
-{
-  switch (option->type) {
-  case I3_OPT_SENDER: 
-    if (option->entry.ret_addr)
-      free_i3_addr(option->entry.ret_addr);
-    break;
-  case I3_OPT_DESTINATION: 
-    if (option->entry.dst_addr)
-      free_i3_addr(option->entry.dst_addr);
-    break;
-  case I3_OPT_TRIGGER_INSERT:
-  case I3_OPT_TRIGGER_CHALLENGE:
-  case I3_OPT_CONSTRAINT_FAILED:
-  case I3_OPT_TRIGGER_ACK: 
-  case I3_OPT_TRIGGER_REMOVE:
-  case I3_OPT_CACHE_ADDR:
-  case I3_OPT_CACHE_DEST_ADDR:
-  case I3_OPT_CACHE_SHORTCUT_ADDR:
-  case I3_OPT_FORCE_CACHE_ADDR:
-  case I3_OPT_ROUTE_BROKEN:
-    if (option->entry.trigger)
-      free_i3_trigger(option->entry.trigger);
-    break;
-  case I3_OPT_TRIGGER_NOT_PRESENT:
-  case I3_OPT_TRIGGER_RATELIMIT:
-    if (option->entry.id)
-      free_i3_id(option->entry.id);
-    break;
-  case I3_OPT_REQUEST_FOR_CACHE:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
-#if NEWS_INSTRUMENT
-  case I3_OPT_LOG_PACKET:
-  case I3_OPT_APPEND_TS:
-#endif
-    break;
-  default:
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "free_i3_option: invalid option 
type: %d\n", option->type);
-  }
-  free(option);
-}
-
-
-i3_option_list *alloc_i3_option_list()
-{
-  i3_option_list *option_list;
-
-  option_list = (i3_option_list *)malloc(sizeof(i3_option_list));
-  if (option_list) {
-    option_list->head = option_list->tail = NULL;
-    return option_list;
-  }
-
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "alloc_i3_option_list: memory 
allocation error.\n");
-  return NULL;
-}
-
-
-void free_i3_option_list(i3_option_list *option_list)
-{
-  i3_option *option;
- 
-  while (option_list->head) {
-    option = option_list->head;
-    option_list->head = option_list->head->next;
-    free_i3_option(option);
-  }
-    
-  free(option_list);
-}
-
-
-
-/***************************************************************************
- * Purpose: To check if an option is "local" to an i3 node
- *         or needs to be forwarded along a path
- * 
- * Example: I3_OPT_LOG_PACKET (ie. instrumenting to log packets)
- *     needs to be forwarded along an i3 path, whereas I3_OPT_SENDER
- *     is just for this i3 node in case any control mesg is returned
- *     
- ***************************************************************************/
-int is_local_option(i3_option *option)
-{
-#ifdef NEWS_INSTRUMENT
-  if (option->type == I3_OPT_LOG_PACKET ||
-      option->type == I3_OPT_APPEND_TS ||
-      option->type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT ||
-      option->type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR) {
-    return FALSE;
-  } else {
-    return TRUE;
-  }
-#else
-  if (option->type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT ||
-      option->type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR) {
-    /* this might be associated to another non-local option */
-    return FALSE;
-  } else {
-    return TRUE;
-  }
-#endif
-}
-
-
-
-/***************************************************************************
- * Purpose: Returns true if the type of the option is valid
- * 
- **************************************************************************/
-int is_valid_option(i3_option *option)
-{
-  char type = option->type;
-
-  if (type == I3_OPT_SENDER ||
-      type == I3_OPT_TRIGGER_INSERT ||
-      type == I3_OPT_TRIGGER_CHALLENGE ||
-      type == I3_OPT_CONSTRAINT_FAILED ||
-      type == I3_OPT_TRIGGER_ACK ||
-      type == I3_OPT_TRIGGER_REMOVE ||
-      type == I3_OPT_TRIGGER_NOT_PRESENT ||
-      type == I3_OPT_TRIGGER_RATELIMIT ||
-      type == I3_OPT_REQUEST_FOR_CACHE ||
-      type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT ||
-      type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR ||
-      type == I3_OPT_ROUTE_BROKEN ||
-      type == I3_OPT_DESTINATION ||
-#if NEWS_INSTRUMENT
-      type == I3_OPT_LOG_PACKET ||
-      type == I3_OPT_APPEND_TS ||
-#endif
-      type == I3_OPT_CACHE_ADDR ||
-      type == I3_OPT_CACHE_DEST_ADDR ||
-      type == I3_OPT_CACHE_SHORTCUT_ADDR ||
-      type == I3_OPT_FORCE_CACHE_ADDR)
-    {
-      return TRUE;
-    } else {
-      return FALSE;
-    }
-}
-
-
-/***************************************************************************
- * Purpose: Find an option of a given type in the option list
- *
- * Return: pointer to option, if option found; NULL otherwise 
- * 
- ***************************************************************************/
-i3_option *get_i3_option_from_list(i3_option_list *option_list, int type)
-{
-  i3_option *o;
-
-  if (option_list == NULL)
-    return NULL;
-
-  for (o = option_list->head; o; o = o->next) 
-    if (o->type == type)
-      return o;
-  return NULL;
-}
-
-
-/***************************************************************************
- * Purpose: Remove all the options that should not be forwarded in
- *     the path, ie. all opts such that is_local_option(opt) is true
- *
- * Return: 0 if there is nothing left in the option list, 1 otherwise
- * 
- ***************************************************************************/
-int remove_local_i3_options(i3_option_list *option_list)
-{
-  i3_option *curr, *next, *prev;
-
-  for (prev = 0, curr = option_list->head; curr != 0;) {
-    next = curr->next;
-    /* save I3_OPT_SENDER option just in case a non-local option needs it */
-    if (is_local_option(curr) && (curr->type != I3_OPT_SENDER)) {
-      free_i3_option(curr);
-      
-      if (NULL == prev)
-       option_list->head = next;
-      else
-       prev->next = next;
-    } else
-      prev = curr;
-    
-    curr = next;
-  }
-  option_list->tail = prev;
-
-  /* check whether there is any non-local option needing I3_OPT_SENDER 
-   * option; if not remove it
-   * XXX - now check only if I3_OPT_SENDER is the only option; 
-   * need to be changed when more non-local options are added
-   */
-  if (  
-            option_list &&  //FIX by Andrei
-            option_list->head == option_list->tail && 
-            option_list->head && //FIX by Andrei
-            option_list->head->type == I3_OPT_SENDER
-        ) {
-    free_i3_option(option_list->head);
-    option_list->head = option_list->tail = NULL;
-  }
-
-  return (NULL != option_list->tail);
-}
-
-
-/***************************************************************************
- * Purpose: Remove a option from the option list 
- *
- * Return: 0 if there is nothing left in the option list, 1 otherwise
- * 
- ***************************************************************************/
-
-int remove_i3_option_from_list(i3_option_list *option_list, i3_option *opt)
-{
-  i3_option *o;
-
-  assert(option_list);
-
-  if (option_list->head == opt) {
-    if (option_list->head == option_list->tail) 
-      /* only option "opt" in the list */
-      option_list->tail = NULL;
-    option_list->head = option_list->head->next;
-    free_i3_option(opt);
-    return (NULL != option_list->tail);
-  }
-
-  for (o = option_list->head; o; o = o->next) {
-    if (o->next == opt) {
-      if (opt == option_list->tail) 
-       /* "opt" is the last option in the list */
-       option_list->tail = o;
-      o->next = o->next->next;
-      free_i3_option(opt);
-    }
-  }
-
-  return (NULL != option_list->tail);
-}
-
-
-/***************************************************************************
- *  append_i3_option - append a new option to the option list
- *
- *  input:
- *    option_list - option list
- *    option - option to be added to the option_list
- ***************************************************************************/
-void append_i3_option(i3_option_list *option_list, 
-                     i3_option *option)
-{
-  if (!option_list->head)
-    option_list->head = option_list->tail = option;
-  else {
-    option_list->tail->next = option;
-    option_list->tail = option;
-  }
-}
- 
-
-/***************************************************************************
- *  pack_i3_option - convert an option data structure in packet format
- *
- *  input:
- *    p - address of the buffer where the option is to be stored in 
- *        packet format (pre-allocated)
- *    option - option data structure to be converted in packet format
- *    
- *  output:
- *    length - length of the option in packet format (bytes)
- ***************************************************************************/
-void pack_i3_option(char *p, i3_option *option, 
-                   unsigned short *length)
-{
-  unsigned short len;
-
-  p[0] = option->type;
-  p++; *length = 1; /* skip option's type */
-
-  switch (option->type) {
-  case I3_OPT_SENDER:
-    pack_i3_addr(p, option->entry.ret_addr, &len);
-    *length += len;
-    break;
-  case I3_OPT_DESTINATION:
-    pack_i3_addr(p, option->entry.dst_addr, &len);
-    *length += len;
-    break;
-  case I3_OPT_TRIGGER_INSERT: 
-  case I3_OPT_TRIGGER_CHALLENGE:
-  case I3_OPT_CONSTRAINT_FAILED:
-  case I3_OPT_TRIGGER_ACK:
-  case I3_OPT_TRIGGER_REMOVE:
-  case I3_OPT_CACHE_ADDR:
-  case I3_OPT_CACHE_DEST_ADDR:
-  case I3_OPT_CACHE_SHORTCUT_ADDR:
-  case I3_OPT_FORCE_CACHE_ADDR:
-  case I3_OPT_ROUTE_BROKEN:
-    pack_i3_trigger(p, option->entry.trigger, &len);
-    *length += len;
-    break;
-  case I3_OPT_TRIGGER_NOT_PRESENT:
-  case I3_OPT_TRIGGER_RATELIMIT:
-    pack_i3_id(p, option->entry.id, &len);
-    *length += len;
-    break;
-  case I3_OPT_REQUEST_FOR_CACHE:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
-#if NEWS_INSTRUMENT
-  case I3_OPT_LOG_PACKET:
-  case I3_OPT_APPEND_TS:
-#endif
-    break;
-  default:
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, 
-               "pack_i3_option: invalid address type %d\n", option->type);
-  }
-}
-
-unsigned short get_i3_option_len(i3_option *option) 
-{
-  unsigned short length;
-
-  length = sizeof(char); /* option type */
-
-  switch (option->type) {
-  case I3_OPT_SENDER:
-    length += get_i3_addr_len(option->entry.ret_addr);
-    break;
-  case I3_OPT_DESTINATION:
-    length += get_i3_addr_len(option->entry.dst_addr);
-    break;
-  case I3_OPT_TRIGGER_INSERT: 
-  case I3_OPT_TRIGGER_CHALLENGE:
-  case I3_OPT_CONSTRAINT_FAILED:
-  case I3_OPT_TRIGGER_ACK:
-  case I3_OPT_TRIGGER_REMOVE:
-  case I3_OPT_CACHE_ADDR:
-  case I3_OPT_CACHE_DEST_ADDR:
-  case I3_OPT_CACHE_SHORTCUT_ADDR:
-  case I3_OPT_FORCE_CACHE_ADDR:
-  case I3_OPT_ROUTE_BROKEN:
-    length += get_i3_trigger_len(option->entry.trigger);
-    break;
-  case I3_OPT_TRIGGER_NOT_PRESENT:
-  case I3_OPT_TRIGGER_RATELIMIT:
-    length += sizeof(ID);
-    break;
-  case I3_OPT_REQUEST_FOR_CACHE:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
-#if NEWS_INSTRUMENT
-  case I3_OPT_LOG_PACKET:
-  case I3_OPT_APPEND_TS:
-#endif
-    break;
-  default:
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "pack_i3_option: invalid address 
type %d\n",option->type);
-  }
-  return length;
-}
-
-
-/***************************************************************************
- *  unpack_i3_option - allocate an i3 option data structure
- *                      and copy info from packet into it
- *
- *  input:
- *    p - address where option is stored in packet format
- *    
- *  output:
- *    length - length of the option in packet format (bytes)
- *
- ***************************************************************************/
-i3_option *unpack_i3_option(char *p, unsigned short *length)
-{
-  i3_option *option = alloc_i3_option();
-  unsigned short len = 0;
-
-  option->type = p[0];
-  p++; *length = 1;
-
-  switch (option->type) {
-  case I3_OPT_SENDER:
-    option->entry.ret_addr = unpack_i3_addr(p, &len);
-    p += len; 
-    *length += len;
-    break;
-  case I3_OPT_DESTINATION:
-    option->entry.dst_addr = unpack_i3_addr(p, &len);
-    p += len; 
-    *length += len;
-    break;
-  case I3_OPT_TRIGGER_INSERT: 
-  case I3_OPT_TRIGGER_CHALLENGE:
-  case I3_OPT_CONSTRAINT_FAILED:
-  case I3_OPT_TRIGGER_ACK:
-  case I3_OPT_TRIGGER_REMOVE:
-  case I3_OPT_CACHE_ADDR:
-  case I3_OPT_CACHE_DEST_ADDR:
-  case I3_OPT_CACHE_SHORTCUT_ADDR:
-  case I3_OPT_FORCE_CACHE_ADDR:
-  case I3_OPT_ROUTE_BROKEN:
-    option->entry.trigger = unpack_i3_trigger(p, &len);
-    *length += len;
-    break;
-  case I3_OPT_TRIGGER_NOT_PRESENT:
-  case I3_OPT_TRIGGER_RATELIMIT:
-    option->entry.id = unpack_i3_id(p, &len);
-    *length += len;
-    break;
-  case I3_OPT_REQUEST_FOR_CACHE:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
-#if NEWS_INSTRUMENT
-  case I3_OPT_LOG_PACKET:
-  case I3_OPT_APPEND_TS:
-#endif
-    option->entry.nothing = (void *)NULL;
-    break;
-  default:
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "unpack_i3_option: invalid address 
type %d\n", option->type);
-  }
-  return option;
-}
-
-/***************************************************************************
- *  check_i3_option - check whether i3 option is well-formed
- *
- *  input:
- *    p - address where option is stored in packet format
- *    
- *  return:
- *    error code; FALSE if no error
-
- *  output:
- *    length - length of the option in packet format (bytes)
- *    
- ***************************************************************************/
-
-int check_i3_option(char *p, unsigned short *length)
-{
-  unsigned short len = 0;
-  char            option_type = p[0], type;
-  int rc;
-
-  p++; *length = 1; /* account for option's type */
-
-  switch (option_type) {
-  case I3_OPT_SENDER:
-  case I3_OPT_DESTINATION:
-    if ((rc = check_i3_addr(p, &len, &type)) != FALSE)
-      return rc;
-    *length += len;
-    break;
-  case I3_OPT_TRIGGER_INSERT: 
-  case I3_OPT_TRIGGER_CHALLENGE:
-  case I3_OPT_CONSTRAINT_FAILED:
-  case I3_OPT_TRIGGER_ACK:
-  case I3_OPT_TRIGGER_REMOVE:
-  case I3_OPT_CACHE_ADDR:
-  case I3_OPT_CACHE_DEST_ADDR:
-  case I3_OPT_CACHE_SHORTCUT_ADDR:
-  case I3_OPT_FORCE_CACHE_ADDR:
-  case I3_OPT_ROUTE_BROKEN:
-    if ((rc = check_i3_trigger(p, &len)) != FALSE)
-      return rc;
-    *length += len;
-    break;
-  case I3_OPT_TRIGGER_NOT_PRESENT:
-  case I3_OPT_TRIGGER_RATELIMIT:
-    *length += sizeof(ID);
-    break;
-  case I3_OPT_REQUEST_FOR_CACHE:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
-#if NEWS_INSTRUMENT
-  case I3_OPT_LOG_PACKET:
-  case I3_OPT_APPEND_TS:
-#endif
-    break;
-  default:
-    return I3_ERR_INVALID_OPTION;
-  }
-
-  return FALSE;
-}
-
-
-/***************************************************************************
- *  pack_i3_option_list - store a list of options in packet format
- *
- *  input:
- *    packedbuff - address of the buffer where the option_list is to 
- *                 be stored in packet format (pre-allocated)
- *    option_list - list of options to be stored in packet format
- *    
- *  output:
- *    length - length of the entire list of option in packet format (bytes)
- ***************************************************************************/
-void pack_i3_option_list(char *packedbuff, 
-                        i3_option_list *option_list, 
-                        unsigned short *length)
-{
-  unsigned short len;
-  char           *p = packedbuff;
-  i3_option *option;
-
-  p += sizeof(unsigned short);      /* skip option list's length field */
-  *length = sizeof(unsigned short); /* account for length field */
-
-  for (option = option_list->head; option; option = option->next) {
-    len = 0;
-    pack_i3_option(p, option, &len);
-    /* set the link flag */
-    p += len;
-    *length += len;  
-  }
-  len = htons(*length);
-  memcpy(packedbuff, (char *)&len, sizeof(unsigned short));
-}
-
-unsigned short get_i3_option_list_len(i3_option_list *option_list)
-{
-  unsigned short length;
-  i3_option      *option;
-
-  length = sizeof(unsigned short); /* account for option list's length field */
-
-  for (option = option_list->head; option; option = option->next) {
-    length += get_i3_option_len(option);
-  }
-
-  return length;
-}
-
-
-/***************************************************************************
- *  unpack_i3_option_list - allocate an option list data structure
- *                          and copy info from packet into it
- *
- *  input:
- *    p - address where the option list is stored in packet format
- *    
- *  output:
- *    length - length of the option list info in packet format (bytes)
- *
- ***************************************************************************/
-i3_option_list *unpack_i3_option_list(char *p, unsigned short *length)
-{
-  unsigned short len, len1;
-  i3_option *option;
-  i3_option_list *option_list = alloc_i3_option_list();
-
-  *length = len1 = ntohs(*(unsigned short *)p); /* get option list's length */
-  len1 -= sizeof(unsigned short); /* skip option list's length field */
-  p += sizeof(unsigned short);
-
-  while (len1) {
-    option = unpack_i3_option(p, &len);
-    append_i3_option(option_list, option);
-    p += len;
-    len1 -= len;
-  }
-
-  return option_list;
-}
-
-/***************************************************************************
- *  check_i3_option_list - check whether the option list is well formatted
- *
- *  input:
- *    p - address where the option list is stored in packet format
- *    
- *  return:
- *    error code; FALSE, if no error
- *
- *  output:
- *    length - length of the option list info in packet format (bytes)
- *
- ***************************************************************************/
-int check_i3_option_list(char *p, unsigned short *length)
-{
-  unsigned short len;
-  int ol_len;
-  int rc;
-
-  ol_len = ntohs(*(unsigned short *)p); /* get option list's length */
-  p += sizeof(unsigned short);
-  *length = sizeof(unsigned short); 
-  ol_len -= sizeof(unsigned short); /* account for option length */ 
-
-  while (ol_len) {
-    rc = check_i3_option(p, &len);
-    if (rc != FALSE)
-      return rc;
-    p += len;
-    ol_len -= len;
-    if (ol_len < 0)
-      return I3_ERR_INVALID_OPTLIST;
-  }
-
-  if (ol_len) /* ol_len should be zero */
-    return I3_ERR_INVALID_OPTLIST;
-    
-  return FALSE;
-}
-
-
-/***************************************************************************
- * duplicate_i3_option_list - perform a deep copy
- **************************************************************************/
-i3_option_list *duplicate_i3_option_list(i3_option_list *option_list)
-{
-    i3_option *option, *new_option;
-    i3_option_list *new_option_list = alloc_i3_option_list();
-    
-    for (option = option_list->head; option; option = option->next) {
-       new_option = duplicate_i3_option(option);
-       append_i3_option(new_option_list, new_option);
-    }
-
-    return new_option_list;
-}
-
-
-/*******************************************
- ** print i3_option; just for debbuging   **
- *******************************************/
-void printf_i3_option(i3_option *option, int indent)
-{
-  char buf[INDENT_BUF_LEN];
-
-  memset(buf, ' ', INDENT_BUF_LEN);
-  buf[indent] = 0;
-
-  printf("%s option type = ", buf);
-  printf_i3_option_type(option->type); printf("\n");
-
-  switch (option->type) {
-  case I3_OPT_SENDER:
-    printf_i3_addr(option->entry.ret_addr, indent + INDENT_CONST);
-    break;
-  case I3_OPT_DESTINATION:
-    printf_i3_addr(option->entry.dst_addr, indent + INDENT_CONST);
-    break;
-  case I3_OPT_TRIGGER_INSERT: 
-  case I3_OPT_TRIGGER_CHALLENGE:
-  case I3_OPT_CONSTRAINT_FAILED:
-  case I3_OPT_TRIGGER_ACK:
-  case I3_OPT_TRIGGER_REMOVE:
-  case I3_OPT_CACHE_ADDR:
-  case I3_OPT_CACHE_DEST_ADDR:
-  case I3_OPT_CACHE_SHORTCUT_ADDR:
-  case I3_OPT_FORCE_CACHE_ADDR:
-  case I3_OPT_ROUTE_BROKEN:
-    printf_i3_trigger(option->entry.trigger, indent + INDENT_CONST);
-    break;
-  case I3_OPT_TRIGGER_NOT_PRESENT:
-  case I3_OPT_TRIGGER_RATELIMIT:
-    printf_i3_id(option->entry.id, indent + INDENT_CONST);
-    break;
-  case I3_OPT_REQUEST_FOR_CACHE:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
-#if NEWS_INSTRUMENT
-  case I3_OPT_LOG_PACKET:
-  case I3_OPT_APPEND_TS:
-#endif
-    break;
-  default:
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "printf_i3_option: invalid address 
type %d\n", option->type);
-  }
-}
-
-
-/**************************
- ** print i3_option_list **
- **************************/
-void printf_i3_option_list(i3_option_list *option_list, int indent)
-{
-  i3_option *option;
-  char buf[INDENT_BUF_LEN];
-
-  memset(buf, ' ', INDENT_BUF_LEN);
-  buf[indent] = 0;
-
-  printf("%s option list:\n", buf);
-
-  for (option = option_list->head; option; option = option->next) 
-   printf_i3_option(option, indent + INDENT_CONST); 
-}
-
-
-void printf_i3_option_type(int option_type)
-{
-  switch (option_type) {
-  case I3_OPT_SENDER:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_SENDER\n");
-    break;
-  case I3_OPT_DESTINATION:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_DESTINATION");
-    break;
-  case I3_OPT_TRIGGER_INSERT: 
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_INSERT");
-    break;
-  case I3_OPT_TRIGGER_CHALLENGE:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_CHALLENG");
-    break;
-  case I3_OPT_CONSTRAINT_FAILED:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_CONSTRAINT_FAILED");
-    break;
-  case I3_OPT_TRIGGER_ACK:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_ACK");
-    break;
-  case I3_OPT_TRIGGER_REMOVE:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_REMOVE");
-    break;
-  case I3_OPT_CACHE_ADDR:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_CACHE_ADDR");
-    break;
-  case I3_OPT_CACHE_DEST_ADDR:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_CACHE_DEST_ADDR");
-    break;
-  case I3_OPT_CACHE_SHORTCUT_ADDR:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_CACHE_SHORTCUT_ADDR");
-    break;
-  case I3_OPT_FORCE_CACHE_ADDR:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_FORCE_CACHE_ADDR");
-    break;
-  case I3_OPT_ROUTE_BROKEN:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_ROUTE_BROKEN");
-    break;
-  case I3_OPT_TRIGGER_NOT_PRESENT:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_NOT_PRESENT");
-    break;
-  case I3_OPT_TRIGGER_RATELIMIT:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_RATELIMIT");
-  case I3_OPT_REQUEST_FOR_CACHE:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_REQUEST_FOR_CACHE");
-    break;
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, 
"I3_OPT_REQUEST_FOR_CACHE_SHORTCUT");
-    break;
-  case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, 
"I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR");
-    break;
-  default:
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "%d", option_type);
-  }
-}
+/***************************************************************************
+*                         i3_options.c  -  description
+*                            -------------------
+*   begin                : Nov 21 2002
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#include "i3.h"
+#include "i3_fun.h"
+#include "i3_debug.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+
+/***************************************************************************
+*  alloc_i3_option - allocate i3 option data structure
+*
+*  return:
+*    pointer to the allocated data structure
+***************************************************************************/
+struct i3_option *alloc_i3_option()
+{
+    struct i3_option *option;
+
+    option = (i3_option *) calloc(1, sizeof(i3_option));
+    if (option) {
+        return option;
+    }
+
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "FATAL ERROR: memory allocation 
error in alloc_i3_option\n");
+    return NULL;
+}
+
+/***************************************************************************
+*  init_i3_option - initialize i3 option data structure
+*
+*  input:
+*    option - data structure to be initialized
+*    type - option type
+*    entry - option entry, e.g., ret_addr, trigger (pre-allocated)
+*
+***************************************************************************/
+void init_i3_option(i3_option *option, char type, void *__RTTI entry)
+{
+    option->type = type;
+    /* all are pointers; just use one type for assigment */
+    if (type == I3_OPT_REQUEST_FOR_CACHE
+        || type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT
+        || type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR
+#if NEWS_INSTRUMENT
+        || type == I3_OPT_LOG_PACKET || type == I3_OPT_APPEND_TS
+#endif
+        ) {
+        option->entry.nothing = (void *) NULL;
+    } else {
+        option->entry.trigger = (i3_trigger *) entry;
+    }
+}
+
+static void *__RTTI duplicate_i3_option_entry(char type, void *__RTTI entry)
+{
+    if (NULL == entry) {
+        return NULL;
+    }
+
+    if (I3_OPT_SENDER == type || I3_OPT_DESTINATION == type) {
+        return duplicate_i3_addr((i3_addr *) entry);
+    } else if (I3_OPT_TRIGGER_INSERT == type ||
+               I3_OPT_TRIGGER_CHALLENGE == type ||
+               I3_OPT_CONSTRAINT_FAILED == type ||
+               I3_OPT_TRIGGER_ACK == type ||
+               I3_OPT_TRIGGER_REMOVE == type ||
+               I3_OPT_CACHE_ADDR == type ||
+               I3_OPT_CACHE_DEST_ADDR == type ||
+               I3_OPT_CACHE_SHORTCUT_ADDR == type ||
+               I3_OPT_FORCE_CACHE_ADDR == type ||
+               I3_OPT_ROUTE_BROKEN == type) {
+        return duplicate_i3_trigger((i3_trigger *) entry);
+    } else if (I3_OPT_TRIGGER_NOT_PRESENT == type ||
+               I3_OPT_TRIGGER_RATELIMIT == type) {
+        return duplicate_i3_id((ID *) entry);
+    } else {
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "duplicate_i3_option: invalid 
option type\n");
+        return NULL;
+    }
+}
+
+i3_option *duplicate_i3_option(i3_option *option)
+{
+    i3_option *new_option = alloc_i3_option();
+
+    new_option->type          = option->type;
+    new_option->entry.trigger = (i3_trigger *)
+                                duplicate_i3_option_entry(option->type, (void 
*) option->entry.trigger);
+
+    return new_option;
+}
+
+/***************************************************************************
+*  free_i3_option - free option data structure
+*
+*  input:
+*    data structure to be freed
+*
+***************************************************************************/
+void free_i3_option(i3_option *option)
+{
+    switch (option->type) {
+    case I3_OPT_SENDER:
+        if (option->entry.ret_addr) {
+            free_i3_addr(option->entry.ret_addr);
+        }
+        break;
+    case I3_OPT_DESTINATION:
+        if (option->entry.dst_addr) {
+            free_i3_addr(option->entry.dst_addr);
+        }
+        break;
+    case I3_OPT_TRIGGER_INSERT:
+    case I3_OPT_TRIGGER_CHALLENGE:
+    case I3_OPT_CONSTRAINT_FAILED:
+    case I3_OPT_TRIGGER_ACK:
+    case I3_OPT_TRIGGER_REMOVE:
+    case I3_OPT_CACHE_ADDR:
+    case I3_OPT_CACHE_DEST_ADDR:
+    case I3_OPT_CACHE_SHORTCUT_ADDR:
+    case I3_OPT_FORCE_CACHE_ADDR:
+    case I3_OPT_ROUTE_BROKEN:
+        if (option->entry.trigger) {
+            free_i3_trigger(option->entry.trigger);
+        }
+        break;
+    case I3_OPT_TRIGGER_NOT_PRESENT:
+    case I3_OPT_TRIGGER_RATELIMIT:
+        if (option->entry.id) {
+            free_i3_id(option->entry.id);
+        }
+        break;
+    case I3_OPT_REQUEST_FOR_CACHE:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
+#if NEWS_INSTRUMENT
+    case I3_OPT_LOG_PACKET:
+    case I3_OPT_APPEND_TS:
+#endif
+        break;
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "free_i3_option: invalid 
option type: %d\n", option->type);
+    }
+    free(option);
+}
+
+i3_option_list *alloc_i3_option_list()
+{
+    i3_option_list *option_list;
+
+    option_list = (i3_option_list *) malloc(sizeof(i3_option_list));
+    if (option_list) {
+        option_list->head = option_list->tail = NULL;
+        return option_list;
+    }
+
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "alloc_i3_option_list: memory 
allocation error.\n");
+    return NULL;
+}
+
+void free_i3_option_list(i3_option_list *option_list)
+{
+    i3_option *option;
+
+    while (option_list->head) {
+        option            = option_list->head;
+        option_list->head = option_list->head->next;
+        free_i3_option(option);
+    }
+
+    free(option_list);
+}
+
+/***************************************************************************
+* Purpose: To check if an option is "local" to an i3 node
+*       or needs to be forwarded along a path
+*
+* Example: I3_OPT_LOG_PACKET (ie. instrumenting to log packets)
+*   needs to be forwarded along an i3 path, whereas I3_OPT_SENDER
+*   is just for this i3 node in case any control mesg is returned
+*
+***************************************************************************/
+int is_local_option(i3_option *option)
+{
+#ifdef NEWS_INSTRUMENT
+    if (option->type == I3_OPT_LOG_PACKET ||
+        option->type == I3_OPT_APPEND_TS ||
+        option->type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT ||
+        option->type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR) {
+        return FALSE;
+    } else {
+        return TRUE;
+    }
+#else
+    if (option->type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT ||
+        option->type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR) {
+        /* this might be associated to another non-local option */
+        return FALSE;
+    } else {
+        return TRUE;
+    }
+#endif
+}
+
+/***************************************************************************
+ * Purpose: Returns true if the type of the option is valid
+ *
+ **************************************************************************/
+int is_valid_option(i3_option *option)
+{
+    char type = option->type;
+
+    if (type == I3_OPT_SENDER ||
+        type == I3_OPT_TRIGGER_INSERT ||
+        type == I3_OPT_TRIGGER_CHALLENGE ||
+        type == I3_OPT_CONSTRAINT_FAILED ||
+        type == I3_OPT_TRIGGER_ACK ||
+        type == I3_OPT_TRIGGER_REMOVE ||
+        type == I3_OPT_TRIGGER_NOT_PRESENT ||
+        type == I3_OPT_TRIGGER_RATELIMIT ||
+        type == I3_OPT_REQUEST_FOR_CACHE ||
+        type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT ||
+        type == I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR ||
+        type == I3_OPT_ROUTE_BROKEN ||
+        type == I3_OPT_DESTINATION ||
+#if NEWS_INSTRUMENT
+        type == I3_OPT_LOG_PACKET ||
+        type == I3_OPT_APPEND_TS ||
+#endif
+        type == I3_OPT_CACHE_ADDR ||
+        type == I3_OPT_CACHE_DEST_ADDR ||
+        type == I3_OPT_CACHE_SHORTCUT_ADDR ||
+        type == I3_OPT_FORCE_CACHE_ADDR) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+/***************************************************************************
+* Purpose: Find an option of a given type in the option list
+*
+* Return: pointer to option, if option found; NULL otherwise
+*
+***************************************************************************/
+i3_option *get_i3_option_from_list(i3_option_list *option_list, int type)
+{
+    i3_option *o;
+
+    if (option_list == NULL) {
+        return NULL;
+    }
+
+    for (o = option_list->head; o; o = o->next) {
+        if (o->type == type) {
+            return o;
+        }
+    }
+    return NULL;
+}
+
+/***************************************************************************
+* Purpose: Remove all the options that should not be forwarded in
+* the path, ie. all opts such that is_local_option(opt) is true
+*
+* Return: 0 if there is nothing left in the option list, 1 otherwise
+*
+***************************************************************************/
+int remove_local_i3_options(i3_option_list *option_list)
+{
+    i3_option *curr, *next, *prev;
+
+    for (prev = 0, curr = option_list->head; curr != 0; ) {
+        next = curr->next;
+        /* save I3_OPT_SENDER option just in case a non-local option needs it 
*/
+        if (is_local_option(curr) && (curr->type != I3_OPT_SENDER)) {
+            free_i3_option(curr);
+
+            if (NULL == prev) {
+                option_list->head = next;
+            } else {
+                prev->next = next;
+            }
+        } else {
+            prev = curr;
+        }
+
+        curr = next;
+    }
+    option_list->tail = prev;
+
+    /* check whether there is any non-local option needing I3_OPT_SENDER
+     * option; if not remove it
+     * XXX - now check only if I3_OPT_SENDER is the only option;
+     * need to be changed when more non-local options are added
+     */
+    if (
+        option_list &&      //FIX by Andrei
+        option_list->head == option_list->tail &&
+        option_list->head &&     //FIX by Andrei
+        option_list->head->type == I3_OPT_SENDER
+        ) {
+        free_i3_option(option_list->head);
+        option_list->head = option_list->tail = NULL;
+    }
+
+    return NULL != option_list->tail;
+}
+
+/***************************************************************************
+* Purpose: Remove a option from the option list
+*
+* Return: 0 if there is nothing left in the option list, 1 otherwise
+*
+***************************************************************************/
+
+int remove_i3_option_from_list(i3_option_list *option_list, i3_option *opt)
+{
+    i3_option *o;
+
+    assert(option_list);
+
+    if (option_list->head == opt) {
+        if (option_list->head == option_list->tail) {
+            /* only option "opt" in the list */
+            option_list->tail = NULL;
+        }
+        option_list->head = option_list->head->next;
+        free_i3_option(opt);
+        return NULL != option_list->tail;
+    }
+
+    for (o = option_list->head; o; o = o->next) {
+        if (o->next == opt) {
+            if (opt == option_list->tail) {
+                /* "opt" is the last option in the list */
+                option_list->tail = o;
+            }
+            o->next = o->next->next;
+            free_i3_option(opt);
+        }
+    }
+
+    return NULL != option_list->tail;
+}
+
+/***************************************************************************
+*  append_i3_option - append a new option to the option list
+*
+*  input:
+*    option_list - option list
+*    option - option to be added to the option_list
+***************************************************************************/
+void append_i3_option(i3_option_list *option_list,
+                      i3_option *option)
+{
+    if (!option_list->head) {
+        option_list->head = option_list->tail = option;
+    } else {
+        option_list->tail->next = option;
+        option_list->tail       = option;
+    }
+}
+
+/***************************************************************************
+*  pack_i3_option - convert an option data structure in packet format
+*
+*  input:
+*    p - address of the buffer where the option is to be stored in
+*        packet format (pre-allocated)
+*    option - option data structure to be converted in packet format
+*
+*  output:
+*    length - length of the option in packet format (bytes)
+***************************************************************************/
+void pack_i3_option(char *p, i3_option *option,
+                    unsigned short *length)
+{
+    unsigned short len;
+
+    p[0]    = option->type;
+    p++;
+    *length = 1;    /* skip option's type */
+
+    switch (option->type) {
+    case I3_OPT_SENDER:
+        pack_i3_addr(p, option->entry.ret_addr, &len);
+        *length += len;
+        break;
+    case I3_OPT_DESTINATION:
+        pack_i3_addr(p, option->entry.dst_addr, &len);
+        *length += len;
+        break;
+    case I3_OPT_TRIGGER_INSERT:
+    case I3_OPT_TRIGGER_CHALLENGE:
+    case I3_OPT_CONSTRAINT_FAILED:
+    case I3_OPT_TRIGGER_ACK:
+    case I3_OPT_TRIGGER_REMOVE:
+    case I3_OPT_CACHE_ADDR:
+    case I3_OPT_CACHE_DEST_ADDR:
+    case I3_OPT_CACHE_SHORTCUT_ADDR:
+    case I3_OPT_FORCE_CACHE_ADDR:
+    case I3_OPT_ROUTE_BROKEN:
+        pack_i3_trigger(p, option->entry.trigger, &len);
+        *length += len;
+        break;
+    case I3_OPT_TRIGGER_NOT_PRESENT:
+    case I3_OPT_TRIGGER_RATELIMIT:
+        pack_i3_id(p, option->entry.id, &len);
+        *length += len;
+        break;
+    case I3_OPT_REQUEST_FOR_CACHE:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
+#if NEWS_INSTRUMENT
+    case I3_OPT_LOG_PACKET:
+    case I3_OPT_APPEND_TS:
+#endif
+        break;
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL,
+                        "pack_i3_option: invalid address type %d\n", 
option->type);
+    }
+}
+
+unsigned short get_i3_option_len(i3_option *option)
+{
+    unsigned short length;
+
+    length = sizeof(char); /* option type */
+
+    switch (option->type) {
+    case I3_OPT_SENDER:
+        length += get_i3_addr_len(option->entry.ret_addr);
+        break;
+    case I3_OPT_DESTINATION:
+        length += get_i3_addr_len(option->entry.dst_addr);
+        break;
+    case I3_OPT_TRIGGER_INSERT:
+    case I3_OPT_TRIGGER_CHALLENGE:
+    case I3_OPT_CONSTRAINT_FAILED:
+    case I3_OPT_TRIGGER_ACK:
+    case I3_OPT_TRIGGER_REMOVE:
+    case I3_OPT_CACHE_ADDR:
+    case I3_OPT_CACHE_DEST_ADDR:
+    case I3_OPT_CACHE_SHORTCUT_ADDR:
+    case I3_OPT_FORCE_CACHE_ADDR:
+    case I3_OPT_ROUTE_BROKEN:
+        length += get_i3_trigger_len(option->entry.trigger);
+        break;
+    case I3_OPT_TRIGGER_NOT_PRESENT:
+    case I3_OPT_TRIGGER_RATELIMIT:
+        length += sizeof(ID);
+        break;
+    case I3_OPT_REQUEST_FOR_CACHE:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
+#if NEWS_INSTRUMENT
+    case I3_OPT_LOG_PACKET:
+    case I3_OPT_APPEND_TS:
+#endif
+        break;
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "pack_i3_option: invalid 
address type %d\n", option->type);
+    }
+    return length;
+}
+
+/***************************************************************************
+*  unpack_i3_option - allocate an i3 option data structure
+*                      and copy info from packet into it
+*
+*  input:
+*    p - address where option is stored in packet format
+*
+*  output:
+*    length - length of the option in packet format (bytes)
+*
+***************************************************************************/
+i3_option *unpack_i3_option(char *p, unsigned short *length)
+{
+    i3_option *option  = alloc_i3_option();
+    unsigned short len = 0;
+
+    option->type = p[0];
+    p++;
+    *length      = 1;
+
+    switch (option->type) {
+    case I3_OPT_SENDER:
+        option->entry.ret_addr = unpack_i3_addr(p, &len);
+        p                     += len;
+        *length               += len;
+        break;
+    case I3_OPT_DESTINATION:
+        option->entry.dst_addr = unpack_i3_addr(p, &len);
+        p                     += len;
+        *length               += len;
+        break;
+    case I3_OPT_TRIGGER_INSERT:
+    case I3_OPT_TRIGGER_CHALLENGE:
+    case I3_OPT_CONSTRAINT_FAILED:
+    case I3_OPT_TRIGGER_ACK:
+    case I3_OPT_TRIGGER_REMOVE:
+    case I3_OPT_CACHE_ADDR:
+    case I3_OPT_CACHE_DEST_ADDR:
+    case I3_OPT_CACHE_SHORTCUT_ADDR:
+    case I3_OPT_FORCE_CACHE_ADDR:
+    case I3_OPT_ROUTE_BROKEN:
+        option->entry.trigger = unpack_i3_trigger(p, &len);
+        *length              += len;
+        break;
+    case I3_OPT_TRIGGER_NOT_PRESENT:
+    case I3_OPT_TRIGGER_RATELIMIT:
+        option->entry.id      = unpack_i3_id(p, &len);
+        *length              += len;
+        break;
+    case I3_OPT_REQUEST_FOR_CACHE:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
+#if NEWS_INSTRUMENT
+    case I3_OPT_LOG_PACKET:
+    case I3_OPT_APPEND_TS:
+#endif
+        option->entry.nothing = (void *) NULL;
+        break;
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "unpack_i3_option: invalid 
address type %d\n", option->type);
+    }
+    return option;
+}
+
+/***************************************************************************
+*  check_i3_option - check whether i3 option is well-formed
+*
+*  input:
+*    p - address where option is stored in packet format
+*
+*  return:
+*    error code; FALSE if no error
+*
+*  output:
+*    length - length of the option in packet format (bytes)
+*
+***************************************************************************/
+
+int check_i3_option(char *p, unsigned short *length)
+{
+    unsigned short len = 0;
+    char option_type   = p[0], type;
+    int rc;
+
+    p++;
+    *length = 1;    /* account for option's type */
+
+    switch (option_type) {
+    case I3_OPT_SENDER:
+    case I3_OPT_DESTINATION:
+        if ((rc = check_i3_addr(p, &len, &type)) != FALSE) {
+            return rc;
+        }
+        *length += len;
+        break;
+    case I3_OPT_TRIGGER_INSERT:
+    case I3_OPT_TRIGGER_CHALLENGE:
+    case I3_OPT_CONSTRAINT_FAILED:
+    case I3_OPT_TRIGGER_ACK:
+    case I3_OPT_TRIGGER_REMOVE:
+    case I3_OPT_CACHE_ADDR:
+    case I3_OPT_CACHE_DEST_ADDR:
+    case I3_OPT_CACHE_SHORTCUT_ADDR:
+    case I3_OPT_FORCE_CACHE_ADDR:
+    case I3_OPT_ROUTE_BROKEN:
+        if ((rc = check_i3_trigger(p, &len)) != FALSE) {
+            return rc;
+        }
+        *length += len;
+        break;
+    case I3_OPT_TRIGGER_NOT_PRESENT:
+    case I3_OPT_TRIGGER_RATELIMIT:
+        *length += sizeof(ID);
+        break;
+    case I3_OPT_REQUEST_FOR_CACHE:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
+#if NEWS_INSTRUMENT
+    case I3_OPT_LOG_PACKET:
+    case I3_OPT_APPEND_TS:
+#endif
+        break;
+    default:
+        return I3_ERR_INVALID_OPTION;
+    }
+
+    return FALSE;
+}
+
+/***************************************************************************
+*  pack_i3_option_list - store a list of options in packet format
+*
+*  input:
+*    packedbuff - address of the buffer where the option_list is to
+*                 be stored in packet format (pre-allocated)
+*    option_list - list of options to be stored in packet format
+*
+*  output:
+*    length - length of the entire list of option in packet format (bytes)
+***************************************************************************/
+void pack_i3_option_list(char *packedbuff,
+                         i3_option_list *option_list,
+                         unsigned short *length)
+{
+    unsigned short len;
+    char *p = packedbuff;
+    i3_option *option;
+
+    p      += sizeof(unsigned short); /* skip option list's length field */
+    *length = sizeof(unsigned short); /* account for length field */
+
+    for (option = option_list->head; option; option = option->next) {
+        len      = 0;
+        pack_i3_option(p, option, &len);
+        /* set the link flag */
+        p       += len;
+        *length += len;
+    }
+    len = htons(*length);
+    memcpy(packedbuff, (char *) &len, sizeof(unsigned short));
+}
+
+unsigned short get_i3_option_list_len(i3_option_list *option_list)
+{
+    unsigned short length;
+    i3_option *option;
+
+    length = sizeof(unsigned short); /* account for option list's length field 
*/
+
+    for (option = option_list->head; option; option = option->next) {
+        length += get_i3_option_len(option);
+    }
+
+    return length;
+}
+
+/***************************************************************************
+*  unpack_i3_option_list - allocate an option list data structure
+*                          and copy info from packet into it
+*
+*  input:
+*    p - address where the option list is stored in packet format
+*
+*  output:
+*    length - length of the option list info in packet format (bytes)
+*
+***************************************************************************/
+i3_option_list *unpack_i3_option_list(char *p, unsigned short *length)
+{
+    unsigned short len, len1;
+    i3_option *option;
+    i3_option_list *option_list = alloc_i3_option_list();
+
+    *length = len1 = ntohs(*(unsigned short *) p); /* get option list's length 
*/
+    len1   -= sizeof(unsigned short); /* skip option list's length field */
+    p      += sizeof(unsigned short);
+
+    while (len1) {
+        option = unpack_i3_option(p, &len);
+        append_i3_option(option_list, option);
+        p     += len;
+        len1  -= len;
+    }
+
+    return option_list;
+}
+
+/***************************************************************************
+*  check_i3_option_list - check whether the option list is well formatted
+*
+*  input:
+*    p - address where the option list is stored in packet format
+*
+*  return:
+*    error code; FALSE, if no error
+*
+*  output:
+*    length - length of the option list info in packet format (bytes)
+*
+***************************************************************************/
+int check_i3_option_list(char *p, unsigned short *length)
+{
+    unsigned short len;
+    int ol_len;
+    int rc;
+
+    ol_len  = ntohs(*(unsigned short *) p); /* get option list's length */
+    p      += sizeof(unsigned short);
+    *length = sizeof(unsigned short);
+    ol_len -= sizeof(unsigned short); /* account for option length */
+
+    while (ol_len) {
+        rc      = check_i3_option(p, &len);
+        if (rc != FALSE) {
+            return rc;
+        }
+        p      += len;
+        ol_len -= len;
+        if (ol_len < 0) {
+            return I3_ERR_INVALID_OPTLIST;
+        }
+    }
+
+    if (ol_len) { /* ol_len should be zero */
+        return I3_ERR_INVALID_OPTLIST;
+    }
+
+    return FALSE;
+}
+
+/***************************************************************************
+ * duplicate_i3_option_list - perform a deep copy
+ **************************************************************************/
+i3_option_list *duplicate_i3_option_list(i3_option_list *option_list)
+{
+    i3_option *option, *new_option;
+    i3_option_list *new_option_list = alloc_i3_option_list();
+
+    for (option = option_list->head; option; option = option->next) {
+        new_option = duplicate_i3_option(option);
+        append_i3_option(new_option_list, new_option);
+    }
+
+    return new_option_list;
+}
+
+/*******************************************
+** print i3_option; just for debbuging   **
+*******************************************/
+void printf_i3_option(i3_option *option, int indent)
+{
+    char buf[INDENT_BUF_LEN];
+
+    memset(buf, ' ', INDENT_BUF_LEN);
+    buf[indent] = 0;
+
+    printf("%s option type = ", buf);
+    printf_i3_option_type(option->type);
+    printf("\n");
+
+    switch (option->type) {
+    case I3_OPT_SENDER:
+        printf_i3_addr(option->entry.ret_addr, indent + INDENT_CONST);
+        break;
+    case I3_OPT_DESTINATION:
+        printf_i3_addr(option->entry.dst_addr, indent + INDENT_CONST);
+        break;
+    case I3_OPT_TRIGGER_INSERT:
+    case I3_OPT_TRIGGER_CHALLENGE:
+    case I3_OPT_CONSTRAINT_FAILED:
+    case I3_OPT_TRIGGER_ACK:
+    case I3_OPT_TRIGGER_REMOVE:
+    case I3_OPT_CACHE_ADDR:
+    case I3_OPT_CACHE_DEST_ADDR:
+    case I3_OPT_CACHE_SHORTCUT_ADDR:
+    case I3_OPT_FORCE_CACHE_ADDR:
+    case I3_OPT_ROUTE_BROKEN:
+        printf_i3_trigger(option->entry.trigger, indent + INDENT_CONST);
+        break;
+    case I3_OPT_TRIGGER_NOT_PRESENT:
+    case I3_OPT_TRIGGER_RATELIMIT:
+        printf_i3_id(option->entry.id, indent + INDENT_CONST);
+        break;
+    case I3_OPT_REQUEST_FOR_CACHE:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
+#if NEWS_INSTRUMENT
+    case I3_OPT_LOG_PACKET:
+    case I3_OPT_APPEND_TS:
+#endif
+        break;
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "printf_i3_option: invalid 
address type %d\n", option->type);
+    }
+}
+
+/**************************
+** print i3_option_list **
+**************************/
+void printf_i3_option_list(i3_option_list *option_list, int indent)
+{
+    i3_option *option;
+    char buf[INDENT_BUF_LEN];
+
+    memset(buf, ' ', INDENT_BUF_LEN);
+    buf[indent] = 0;
+
+    printf("%s option list:\n", buf);
+
+    for (option = option_list->head; option; option = option->next) {
+        printf_i3_option(option, indent + INDENT_CONST);
+    }
+}
+
+void printf_i3_option_type(int option_type)
+{
+    switch (option_type) {
+    case I3_OPT_SENDER:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_SENDER\n");
+        break;
+    case I3_OPT_DESTINATION:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_DESTINATION");
+        break;
+    case I3_OPT_TRIGGER_INSERT:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_INSERT");
+        break;
+    case I3_OPT_TRIGGER_CHALLENGE:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_CHALLENG");
+        break;
+    case I3_OPT_CONSTRAINT_FAILED:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_CONSTRAINT_FAILED");
+        break;
+    case I3_OPT_TRIGGER_ACK:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_ACK");
+        break;
+    case I3_OPT_TRIGGER_REMOVE:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_REMOVE");
+        break;
+    case I3_OPT_CACHE_ADDR:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_CACHE_ADDR");
+        break;
+    case I3_OPT_CACHE_DEST_ADDR:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_CACHE_DEST_ADDR");
+        break;
+    case I3_OPT_CACHE_SHORTCUT_ADDR:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_CACHE_SHORTCUT_ADDR");
+        break;
+    case I3_OPT_FORCE_CACHE_ADDR:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_FORCE_CACHE_ADDR");
+        break;
+    case I3_OPT_ROUTE_BROKEN:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_ROUTE_BROKEN");
+        break;
+    case I3_OPT_TRIGGER_NOT_PRESENT:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_NOT_PRESENT");
+        break;
+    case I3_OPT_TRIGGER_RATELIMIT:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_TRIGGER_RATELIMIT");
+    case I3_OPT_REQUEST_FOR_CACHE:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "I3_OPT_REQUEST_FOR_CACHE");
+        break;
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, 
"I3_OPT_REQUEST_FOR_CACHE_SHORTCUT");
+        break;
+    case I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, 
"I3_OPT_REQUEST_FOR_CACHE_SHORTCUT_INDIR");
+        break;
+    default:
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "%d", option_type);
+    }
+}

=== modified file 'i3/i3/i3_options.h'
--- i3/i3/i3_options.h  2010-01-06 22:17:32 +0000
+++ i3/i3/i3_options.h  2010-02-11 11:49:47 +0000
@@ -1,41 +1,41 @@
-/***************************************************************************
-                          i3_options.h  -  description
-                             -------------------
-    begin                : Fre Jun 20 2003
-    copyright            : (C) 2003 by klaus
-    email                : wehrle@xxxxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef I3_OPTIONS_H
-#define I3_OPTIONS_H
-
-/* functions implemented in i3_options.c */
-i3_option *alloc_i3_option(void);
-void init_i3_option(i3_option *option, char type, void *entry);
-void free_i3_option(i3_option *option);
-int is_local_option(i3_option *option);
-int is_valid_option(i3_option *option);
-i3_option_list *alloc_i3_option_list(void);
-void free_i3_option_list(i3_option_list *option_list);
-i3_option *get_i3_option_from_list(i3_option_list *option_list, int type);
-int remove_local_i3_options(i3_option_list *option_list);
-int remove_i3_option_from_list(i3_option_list *option_list, i3_option *opt);
-
-void append_i3_option(i3_option_list *option_list,
-                     i3_option *option);
-void pack_i3_option(char *packedbuff, i3_option *option,
-                   unsigned short *length);
-unsigned short get_i3_option_len(i3_option *option); 
-i3_option *unpack_i3_option(char *p, unsigned short *length);
-int check_i3_option(char *p, unsigned short *length);
-int sizeof_i3_option(char *p);
-void pack_i3_option_list(char *p, i3_option_list *option_list,
-                        unsigned short *length);
-unsigned short get_i3_option_list_len(i3_option_list *option_list);
-i3_option_list *unpack_i3_option_list(char *p, unsigned short *length);
-int check_i3_option_list(char *p, unsigned short *length);
-i3_option_list *duplicate_i3_option_list(i3_option_list *opt_list);
-void printf_i3_option(i3_option *option, int intend);
-void printf_i3_option_list(i3_option_list *option_list, int intend);
-void printf_i3_option_type(int option_type);
-#endif
+/***************************************************************************
+*                         i3_options.h  -  description
+*                            -------------------
+*   begin                : Fre Jun 20 2003
+*   copyright            : (C) 2003 by klaus
+*   email                : wehrle@xxxxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef I3_OPTIONS_H
+#define I3_OPTIONS_H
+
+/* functions implemented in i3_options.c */
+i3_option *alloc_i3_option(void);
+void init_i3_option(i3_option *option, char type, void *entry);
+void free_i3_option(i3_option *option);
+int is_local_option(i3_option *option);
+int is_valid_option(i3_option *option);
+i3_option_list *alloc_i3_option_list(void);
+void free_i3_option_list(i3_option_list *option_list);
+i3_option *get_i3_option_from_list(i3_option_list *option_list, int type);
+int remove_local_i3_options(i3_option_list *option_list);
+int remove_i3_option_from_list(i3_option_list *option_list, i3_option *opt);
+
+void append_i3_option(i3_option_list *option_list,
+                      i3_option *option);
+void pack_i3_option(char *packedbuff, i3_option *option,
+                    unsigned short *length);
+unsigned short get_i3_option_len(i3_option *option);
+i3_option *unpack_i3_option(char *p, unsigned short *length);
+int check_i3_option(char *p, unsigned short *length);
+int sizeof_i3_option(char *p);
+void pack_i3_option_list(char *p, i3_option_list *option_list,
+                         unsigned short *length);
+unsigned short get_i3_option_list_len(i3_option_list *option_list);
+i3_option_list *unpack_i3_option_list(char *p, unsigned short *length);
+int check_i3_option_list(char *p, unsigned short *length);
+i3_option_list *duplicate_i3_option_list(i3_option_list *opt_list);
+void printf_i3_option(i3_option *option, int intend);
+void printf_i3_option_list(i3_option_list *option_list, int intend);
+void printf_i3_option_type(int option_type);
+#endif

=== modified file 'i3/i3/i3_ping.c'
--- i3/i3/i3_ping.c     2009-12-11 22:49:11 +0000
+++ i3/i3/i3_ping.c     2010-02-11 11:49:47 +0000
@@ -12,79 +12,77 @@
 #define MAX_PACKET_SIZE 2000
 
 /* packet offsets for seq and time */
-#define i3_ping_pkt_seq_offset(p) ((p)+1)
-#define i3_ping_pkt_time_offset(p) ((p)+3)
+#define i3_ping_pkt_seq_offset(p) ((p) + 1)
+#define i3_ping_pkt_time_offset(p) ((p) + 3)
 
 
 /* True if the packet is a request to the i3 server to echo the pkt */
 char is_i3_echo_request(char *p)
 {
-    return (((*p) & I3_PING_PKT) == 1);
+    return ((*p) & I3_PING_PKT) == 1;
 }
 
-
 /* Echo request to an i3 server with addr and port */
 void i3_echo_request(nw_skt_t fd, uint32_t addr, uint16_t port, uint16_t seq)
 {
     struct sockaddr_in to_addr;
     int rc;
     char p[ECHO_PACKET_SIZE];
-    
+
     memset((void *) &to_addr, 0, sizeof(struct sockaddr_in));
-    to_addr.sin_family = AF_INET;
+    to_addr.sin_family      = AF_INET;
     to_addr.sin_addr.s_addr = htonl(addr);
-    to_addr.sin_port = htons(port);
+    to_addr.sin_port        = htons(port);
 
-    p[0] = I3_PING_PKT;                                        // ping packet
-    hnputs(i3_ping_pkt_seq_offset(p), seq);            // seq number
-    hnput64(i3_ping_pkt_time_offset(p), wall_time());  // curr time
+    p[0]                    = I3_PING_PKT;              // ping packet
+    hnputs(i3_ping_pkt_seq_offset(p), seq);             // seq number
+    hnput64(i3_ping_pkt_time_offset(p), wall_time());   // curr time
 
     // TODO: Possible problem
     rc = sendto(fd, p, ECHO_PACKET_SIZE, 0,
-            (struct sockaddr *)&to_addr, sizeof(to_addr));
-    if (rc < 0)
+                (struct sockaddr *) &to_addr, sizeof(to_addr));
+    if (rc < 0) {
         perror("Echo request");
-
+    }
 }
 
-
 /* Echo reply (by i3_server back to monitor) */
 void i3_echo_reply(nw_skt_t fd, char *p, int len, struct sockaddr_in *addr)
 {
     struct sockaddr_in to_addr;
     int rc;
-    
+
     memset((void *) &to_addr, 0, sizeof(struct sockaddr_in));
-    to_addr.sin_family = AF_INET;
+    to_addr.sin_family      = AF_INET;
     to_addr.sin_addr.s_addr = htonl(addr->sin_addr.s_addr);
-    to_addr.sin_port = htons(addr->sin_port);
+    to_addr.sin_port        = htons(addr->sin_port);
 
-    rc = sendto(fd, p, len, 0, (struct sockaddr *)&to_addr, sizeof(to_addr));
-    if (rc < 0)
-       perror("Echo reply");
+    rc                      = sendto(fd, p, len, 0, (struct sockaddr *) 
&to_addr, sizeof(to_addr));
+    if (rc < 0) {
+        perror("Echo reply");
+    }
 }
 
-
 /* Receive echo reply */
 int recv_i3_echo_reply(nw_skt_t fd, uint32_t *addr, uint16_t *port,
-                                uint16_t *seq, uint64_t *rtt)
+                       uint16_t *seq, uint64_t *rtt)
 {
     static char buf[MAX_PACKET_SIZE];
     struct sockaddr_in saddr;
     int len = sizeof(struct sockaddr_in);
     int rc;
-    
-    rc = recvfrom(fd, buf, MAX_PACKET_SIZE, 0, (struct sockaddr *)&saddr, 
(socklen_t *) &len);
+
+    rc = recvfrom(fd, buf, MAX_PACKET_SIZE, 0, (struct sockaddr *) &saddr, 
(socklen_t *) &len);
     if (rc < 0) {
-       perror("recvfrom");
-       return -1;
+        perror("recvfrom");
+        return -1;
     }
     if (I3_PING_PKT != buf[0]) {
-       return -1;
+        return -1;
     }
     *addr = ntohl(saddr.sin_addr.s_addr);
     *port = ntohs(saddr.sin_port);
-    *seq = nhgets(i3_ping_pkt_seq_offset(buf));
-    *rtt = wall_time() - nhget64(i3_ping_pkt_time_offset(buf));
+    *seq  = nhgets(i3_ping_pkt_seq_offset(buf));
+    *rtt  = wall_time() - nhget64(i3_ping_pkt_time_offset(buf));
     return 1;
 }

=== modified file 'i3/i3/i3_ping.h'
--- i3/i3/i3_ping.h     2009-12-11 22:49:11 +0000
+++ i3/i3/i3_ping.h     2010-02-11 11:49:47 +0000
@@ -11,9 +11,9 @@
 #endif
 
 void i3_echo_reply(nw_skt_t fd, char *p, int len, struct sockaddr_in *addr);
-void i3_echo_request(nw_skt_t fd, uint32_t addr, uint16_t port, uint16_t seq); 
  
+void i3_echo_request(nw_skt_t fd, uint32_t addr, uint16_t port, uint16_t seq);
 int recv_i3_echo_reply(nw_skt_t fd, uint32_t *addr, uint16_t *port,
-                               uint16_t *seq, uint64_t *rtt);
+                       uint16_t *seq, uint64_t *rtt);
 char is_i3_echo_request(char *p);
 
 #endif

=== modified file 'i3/i3/i3_stack.c'
--- i3/i3/i3_stack.c    2009-12-11 22:49:11 +0000
+++ i3/i3/i3_stack.c    2010-02-11 11:49:47 +0000
@@ -1,249 +1,248 @@
-/***************************************************************************
-                          i3_stack.c  -  description
-                             -------------------
-    begin                : Nov 20 2002
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#include "i3.h"
-#include "i3_fun.h"
-#include "i3_debug.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-/***************************************************************************
- *  alloc_i3_stack - allocate a stack data structure
- *
- *  return:
- *    pointer to the allocated stack 
- ***************************************************************************/
-
-i3_stack *alloc_i3_stack()
-{
-  i3_stack *stack;
-
-  stack = (i3_stack *)malloc(sizeof(i3_stack));
-  if (stack) {
-    stack->ids = NULL;
-    return stack;
-  }
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,"alloc_i3_stack: memory allocation 
error.\n");
-  return NULL;
-}
-
-
-/***************************************************************************
- *  alloc_i3_stack - allocate a stack data structure, and initialize
- *                   its fields
- *
- *  return:
- *    pointer to the allocated stack 
- ***************************************************************************/
-
-void init_i3_stack(i3_stack *s, ID *ids, int len)
-{
-  s->len = len;
-  s->ids = (ID *)malloc(sizeof(ID)*len);
-  if (s->ids) {
-    memcpy((char *)s->ids, ids, sizeof(ID)*len);
-    return;
-  }
-
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,"init_i3_stack: memory allocation 
error.\n");
-}
-
-void init_i3_stack2(i3_stack *s, ID **ids, int len)
-{
-  int i;
-
-  s->len = len;
-  s->ids = (ID *)malloc(sizeof(ID)*len);
-
-  if (s->ids) {
-    for (i = 0; i < len; i++) 
-      memcpy((char *)s->ids, ids[i], sizeof(ID));
-    return;
-  }
-
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,"init_i3_stack2: memory allocation 
error.\n");
-}
-
-
-/***************************************************************************
- *  free_i3_stack - free stack data structure including its list of IDs 
- *
- *  input:
- *    stack to be freed
- ***************************************************************************/
-
-void free_i3_stack(i3_stack *stack)
-{
-  if (stack->ids)
-    free(stack->ids);
-  free(stack);
-}
-
-
-/***************************************************************************
- *  duplicate_i3_stack - create a replica of stack s
- *
- *  input:
- *    s - stack to be duplicated
- *
- *  return:
- *    replica of s
- ***************************************************************************/
-
-i3_stack *duplicate_i3_stack(i3_stack *s)
-{
-  i3_stack *snew = alloc_i3_stack();
-
-  snew->len = s->len;
-  if ((snew->ids = (ID *)malloc(sizeof(ID)*s->len))) {
-    memcpy((char *)snew->ids, (char *)s->ids, sizeof(ID)*s->len);
-    return snew;
-  }
-
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,"init_i3_stack: memory allocation 
error.\n");
-  return NULL;
-}
-
-
-
-
-/***************************************************************************
- *  pack_i3_stack - convert a stack data structure in packet format
- *
- *  input:
- *    p - address of the buffer where the stack is to be stored in 
- *        packet format (the buffer is pre-allocated)
- *    stack - stack to be converted in packet format
- *    
- *  output:
- *    length - length of the stack in packet format
- ***************************************************************************/
-
-void pack_i3_stack(char *p, i3_stack *stack, unsigned short *length)
-{
-  int i;
-  int num_ids;
-
-  num_ids = (stack ? stack->len : 0);
-
-  *p = (*p & 0xf0) + num_ids; /* init stack length */
-  *length = sizeof(char); p += sizeof(char); /* skip stack len */
-
-  if (!num_ids) return; /* no stack to pack */
-
-  for (i = 0; i < num_ids; i++) { 
-    memcpy(p, (char *)&stack->ids[i].x, sizeof(ID));
-    *length += sizeof(ID); p += sizeof(ID);
-  }
-}
-
-unsigned short get_i3_stack_len(i3_stack *stack)
-{
-  int num_ids;
-
-  num_ids = (stack ? stack->len : 0);
-
-  return (unsigned short) (sizeof(char) + num_ids*sizeof(ID)); 
-}
-
-
-/***************************************************************************
- *  unpack_i3_stack - copy stack info from packet to a stack 
- *                      data structure 
- *
- *  input:
- *    p - address where stack is stored in packet format
- *   
- *  return:
- *    stack data structure
- * 
- *  output:
- *    length - length of the stack info in packet format
- *
- ***************************************************************************/
-
-i3_stack *unpack_i3_stack(char *p, unsigned short *length)
-{
-  int i, len;
-  i3_stack *stack;
-
-  len = *p & 0xf;
-  
-  if (!len) {
-    /* there is no stack */
-    *length = sizeof(char);
-    return NULL;
-  }
-
-  stack = alloc_i3_stack();
-  stack->len = len;
-  *length = sizeof(char); 
-  p += sizeof(char); /* skip stack len field */
-
-  if (!(stack->ids = (ID*)malloc(stack->len*sizeof(ID))))
-    panic("unpack_i3_stack: memory allocation error!\n");
-  
-  for (i = 0; i < stack->len; i++) { 
-    memcpy((char *)&stack->ids[i].x, p, sizeof(ID));
-    *length += sizeof(ID); p += sizeof(ID);
-  }
-
-  return stack;
-}
-
-
-/***************************************************************************
- *  check_i3_stack - check i3_stack whether is well-formed
- *
- *  input:
- *    p - address where stack is stored in packet format
- *   
- *  return:
- *    error code; FALSE if no error
- * 
- *  output:
- *    length - length of the stack info in packet format
- *
- ***************************************************************************/
-
-int check_i3_stack(char *p, unsigned short *length)
-{
-  int len = *p & 0xf;
-  
-  *length = (int) (sizeof(char) + len*sizeof(ID));
-  return FALSE;
-}
-
-
-/*************************************
- ** print i3_stack; just for test   **
- *************************************/
-
-void printf_i3_stack(i3_stack *stack, int indent)
-{
-   char buf[INDENT_BUF_LEN];
-   int i;
-   uint k;
-
-  memset(buf, ' ', INDENT_BUF_LEN);
-  buf[indent] = 0;
-
-  printf("%s stack:\n", buf);
-
-  if (!stack)
-    return;
-
-  for (i = 0; i < stack->len; i++) {
-    printf("%s   id(%u) = ", buf, i);
-    for (k = 0; k < sizeof(ID); k++)
-      printf("%x.", (int)(stack->ids[i].x[k])); 
-    printf("\n");
-  }
-}
-
+/***************************************************************************
+*                         i3_stack.c  -  description
+*                            -------------------
+*   begin                : Nov 20 2002
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#include "i3.h"
+#include "i3_fun.h"
+#include "i3_debug.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+/***************************************************************************
+*  alloc_i3_stack - allocate a stack data structure
+*
+*  return:
+*    pointer to the allocated stack
+***************************************************************************/
+
+i3_stack *alloc_i3_stack()
+{
+    i3_stack *stack;
+
+    stack = (i3_stack *) malloc(sizeof(i3_stack));
+    if (stack) {
+        stack->ids = NULL;
+        return stack;
+    }
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "alloc_i3_stack: memory allocation 
error.\n");
+    return NULL;
+}
+
+/***************************************************************************
+*  alloc_i3_stack - allocate a stack data structure, and initialize
+*                   its fields
+*
+*  return:
+*    pointer to the allocated stack
+***************************************************************************/
+
+void init_i3_stack(i3_stack *s, ID *ids, int len)
+{
+    s->len = len;
+    s->ids = (ID *) malloc(sizeof(ID) * len);
+    if (s->ids) {
+        memcpy((char *) s->ids, ids, sizeof(ID) * len);
+        return;
+    }
+
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "init_i3_stack: memory allocation 
error.\n");
+}
+
+void init_i3_stack2(i3_stack *s, ID **ids, int len)
+{
+    int i;
+
+    s->len = len;
+    s->ids = (ID *) malloc(sizeof(ID) * len);
+
+    if (s->ids) {
+        for (i = 0; i < len; i++) {
+            memcpy((char *) s->ids, ids[i], sizeof(ID));
+        }
+        return;
+    }
+
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "init_i3_stack2: memory allocation 
error.\n");
+}
+
+/***************************************************************************
+*  free_i3_stack - free stack data structure including its list of IDs
+*
+*  input:
+*    stack to be freed
+***************************************************************************/
+
+void free_i3_stack(i3_stack *stack)
+{
+    if (stack->ids) {
+        free(stack->ids);
+    }
+    free(stack);
+}
+
+/***************************************************************************
+*  duplicate_i3_stack - create a replica of stack s
+*
+*  input:
+*    s - stack to be duplicated
+*
+*  return:
+*    replica of s
+***************************************************************************/
+
+i3_stack *duplicate_i3_stack(i3_stack *s)
+{
+    i3_stack *snew = alloc_i3_stack();
+
+    snew->len = s->len;
+    if ((snew->ids = (ID *) malloc(sizeof(ID) * s->len))) {
+        memcpy((char *) snew->ids, (char *) s->ids, sizeof(ID) * s->len);
+        return snew;
+    }
+
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "init_i3_stack: memory allocation 
error.\n");
+    return NULL;
+}
+
+/***************************************************************************
+*  pack_i3_stack - convert a stack data structure in packet format
+*
+*  input:
+*    p - address of the buffer where the stack is to be stored in
+*        packet format (the buffer is pre-allocated)
+*    stack - stack to be converted in packet format
+*
+*  output:
+*    length - length of the stack in packet format
+***************************************************************************/
+
+void pack_i3_stack(char *p, i3_stack *stack, unsigned short *length)
+{
+    int i;
+    int num_ids;
+
+    num_ids = (stack ? stack->len : 0);
+
+    *p      = (*p & 0xf0) + num_ids; /* init stack length */
+    *length = sizeof(char);
+    p      += sizeof(char);                  /* skip stack len */
+
+    if (!num_ids) {
+        return;         /* no stack to pack */
+    }
+    for (i = 0; i < num_ids; i++) {
+        memcpy(p, (char *) &stack->ids[i].x, sizeof(ID));
+        *length += sizeof(ID);
+        p       += sizeof(ID);
+    }
+}
+
+unsigned short get_i3_stack_len(i3_stack *stack)
+{
+    int num_ids;
+
+    num_ids = (stack ? stack->len : 0);
+
+    return (unsigned short) (sizeof(char) + num_ids * sizeof(ID));
+}
+
+/***************************************************************************
+*  unpack_i3_stack - copy stack info from packet to a stack
+*                      data structure
+*
+*  input:
+*    p - address where stack is stored in packet format
+*
+*  return:
+*    stack data structure
+*
+*  output:
+*    length - length of the stack info in packet format
+*
+***************************************************************************/
+
+i3_stack *unpack_i3_stack(char *p, unsigned short *length)
+{
+    int i, len;
+    i3_stack *stack;
+
+    len = *p & 0xf;
+
+    if (!len) {
+        /* there is no stack */
+        *length = sizeof(char);
+        return NULL;
+    }
+
+    stack      = alloc_i3_stack();
+    stack->len = len;
+    *length    = sizeof(char);
+    p         += sizeof(char); /* skip stack len field */
+
+    if (!(stack->ids = (ID *) malloc(stack->len * sizeof(ID)))) {
+        panic("unpack_i3_stack: memory allocation error!\n");
+    }
+
+    for (i = 0; i < stack->len; i++) {
+        memcpy((char *) &stack->ids[i].x, p, sizeof(ID));
+        *length += sizeof(ID);
+        p       += sizeof(ID);
+    }
+
+    return stack;
+}
+
+/***************************************************************************
+*  check_i3_stack - check i3_stack whether is well-formed
+*
+*  input:
+*    p - address where stack is stored in packet format
+*
+*  return:
+*    error code; FALSE if no error
+*
+*  output:
+*    length - length of the stack info in packet format
+*
+***************************************************************************/
+
+int check_i3_stack(char *p, unsigned short *length)
+{
+    int len = *p & 0xf;
+
+    *length = (int) (sizeof(char) + len * sizeof(ID));
+    return FALSE;
+}
+
+/*************************************
+** print i3_stack; just for test   **
+*************************************/
+
+void printf_i3_stack(i3_stack *stack, int indent)
+{
+    char buf[INDENT_BUF_LEN];
+    int i;
+    uint k;
+
+    memset(buf, ' ', INDENT_BUF_LEN);
+    buf[indent] = 0;
+
+    printf("%s stack:\n", buf);
+
+    if (!stack) {
+        return;
+    }
+
+    for (i = 0; i < stack->len; i++) {
+        printf("%s   id(%u) = ", buf, i);
+        for (k = 0; k < sizeof(ID); k++) {
+            printf("%x.", (int) (stack->ids[i].x[k]));
+        }
+        printf("\n");
+    }
+}

=== modified file 'i3/i3/i3_stack.h'
--- i3/i3/i3_stack.h    2010-01-06 22:17:32 +0000
+++ i3/i3/i3_stack.h    2010-02-11 11:49:47 +0000
@@ -1,26 +1,26 @@
-/***************************************************************************
-                          i3_stack.h  -  description
-                             -------------------
-    begin                : Fre Jun 20 2003
-    copyright            : (C) 2003 by klaus
-    email                : wehrle@xxxxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef I3_STACK_H
-#define I3_STACK_H
- 
-/* functions implemented in i3_stack.c */
-i3_stack *alloc_i3_stack(void);
-void init_i3_stack(i3_stack *s, ID *ids, int len);
-void init_i3_stack2(i3_stack *s, ID **ids, int len);
-void free_i3_stack(i3_stack *stack);
-void pack_i3_stack(char *packedstack, i3_stack *stack,
-                  unsigned short *length);
-unsigned short get_i3_stack_len(i3_stack *stack);
-i3_stack *unpack_i3_stack(char *p, unsigned short *length);
-int check_i3_stack(char *p, unsigned short *length);
-void printf_i3_stack(i3_stack *stack, int intend);
-i3_stack *duplicate_i3_stack(i3_stack *s);
-
-
-#endif
+/***************************************************************************
+*                         i3_stack.h  -  description
+*                            -------------------
+*   begin                : Fre Jun 20 2003
+*   copyright            : (C) 2003 by klaus
+*   email                : wehrle@xxxxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef I3_STACK_H
+#define I3_STACK_H
+
+/* functions implemented in i3_stack.c */
+i3_stack *alloc_i3_stack(void);
+void init_i3_stack(i3_stack *s, ID *ids, int len);
+void init_i3_stack2(i3_stack *s, ID **ids, int len);
+void free_i3_stack(i3_stack *stack);
+void pack_i3_stack(char *packedstack, i3_stack *stack,
+                   unsigned short *length);
+unsigned short get_i3_stack_len(i3_stack *stack);
+i3_stack *unpack_i3_stack(char *p, unsigned short *length);
+int check_i3_stack(char *p, unsigned short *length);
+void printf_i3_stack(i3_stack *stack, int intend);
+i3_stack *duplicate_i3_stack(i3_stack *s);
+
+
+#endif

=== modified file 'i3/i3/i3_tcp_fns.c'
--- i3/i3/i3_tcp_fns.c  2009-12-29 15:10:11 +0000
+++ i3/i3/i3_tcp_fns.c  2010-02-11 11:49:47 +0000
@@ -1,87 +1,87 @@
-#include "i3_tcp_fns.h"
-#include "../utils/byteorder.h"
-#include "i3_debug.h"
-
-#include <stdio.h>
-#include <assert.h>
-#include <sys/types.h>
-#include "../utils/netwrap.h"
-
-/* Purpose: Send i3 data on TCP socket 
- * Note: To avoid copying of packets, the two sends are performed */
-int send_tcp(char *p, int len, nw_skt_t fd)
-{
-    char header[TCP_I3_HEADER_SIZE];
-
-       
-    /* Send header */
-    header[0] = TCP_I3_HEADER_MAGIC;
-    hnputs(header + 1, (uint16_t) len);
-    
-    if (send(fd, header, TCP_I3_HEADER_SIZE, 0) != TCP_I3_HEADER_SIZE) {
-           perror("TCP header send");
-           return -1;
-    }
-
-    /* Send rest of the packet */
-    if (send(fd, p, len, 0) < len) {
-           perror("TCP Send");
-           return -1;
-    }
-
-    return len;
-}
-
-/* Purpose: Recv i3 data on TCP socket */
-#define MAX_ATTEMPTS 10
-int recv_tcp(char *p, int len, nw_skt_t fd)
-{
-    int recv_len, pkt_size = 0, total_recv_len = 0, num_attempts = 0;
-
-    if (fd < 0) {
-        //TODO XXX Fix this..
-        I3_PRINT_DEBUG1 (I3_DEBUG_LEVEL_VERBOSE, "invalid fd = %d\n",fd);
-        return -1;
-    }
-
-    /* recv header */
-    recv_len = recv(fd, p, TCP_I3_HEADER_SIZE, 0);
-    if (recv_len < 0) {
-           perror("TCP header recv");
-        fprintf (stderr, " on fd %d\n\n", fd);
-        nw_close (fd);
-           return recv_len;
-    }
-    
-    /* recv rest of the packet */
-    if (recv_len > 0) {
-      if( (TCP_I3_HEADER_MAGIC != p[0]) ||     // Invalid packet; Not i3?
-         (recv_len < TCP_I3_HEADER_SIZE) ) {
-       I3_PRINT_INFO1 (I3_INFO_LEVEL_WARNING,
-                   "Invalid i3 tcp header on fd %d\n", fd);
-       return -1;
-      }
-      pkt_size = nhgets(p + 1);
-      if (len < pkt_size) {    // Invalid size
-       I3_PRINT_INFO2 (I3_INFO_LEVEL_WARNING,
-                   "Invalid i3 tcp packet size %d (on fd %d)\n",
-                   pkt_size, fd);
-       return -1;
-      }      
-
-           while (pkt_size > 0 && num_attempts++ < MAX_ATTEMPTS) {
-               recv_len = recv(fd, p, pkt_size, 0);
-               total_recv_len += recv_len;
-               pkt_size -= recv_len;
-               p += recv_len;
-           }
-    }
-    
-    /* Hack! */
-    if (pkt_size > 0) {
-           I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "Still some more bytes to 
be received, quitting!\n");
-           return -1;
-    } else {
-           return total_recv_len;
-    }
-}
+#include "i3_tcp_fns.h"
+#include "../utils/byteorder.h"
+#include "i3_debug.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <sys/types.h>
+#include "../utils/netwrap.h"
+
+/* Purpose: Send i3 data on TCP socket
+ * Note: To avoid copying of packets, the two sends are performed */
+int send_tcp(char *p, int len, nw_skt_t fd)
+{
+    char header[TCP_I3_HEADER_SIZE];
+
+
+    /* Send header */
+    header[0] = TCP_I3_HEADER_MAGIC;
+    hnputs(header + 1, (uint16_t) len);
+
+    if (send(fd, header, TCP_I3_HEADER_SIZE, 0) != TCP_I3_HEADER_SIZE) {
+        perror("TCP header send");
+        return -1;
+    }
+
+    /* Send rest of the packet */
+    if (send(fd, p, len, 0) < len) {
+        perror("TCP Send");
+        return -1;
+    }
+
+    return len;
+}
+
+/* Purpose: Recv i3 data on TCP socket */
+#define MAX_ATTEMPTS 10
+int recv_tcp(char *p, int len, nw_skt_t fd)
+{
+    int recv_len, pkt_size = 0, total_recv_len = 0, num_attempts = 0;
+
+    if (fd < 0) {
+        //TODO XXX Fix this..
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_VERBOSE, "invalid fd = %d\n", fd);
+        return -1;
+    }
+
+    /* recv header */
+    recv_len = recv(fd, p, TCP_I3_HEADER_SIZE, 0);
+    if (recv_len < 0) {
+        perror("TCP header recv");
+        fprintf(stderr, " on fd %d\n\n", fd);
+        nw_close(fd);
+        return recv_len;
+    }
+
+    /* recv rest of the packet */
+    if (recv_len > 0) {
+        if ((TCP_I3_HEADER_MAGIC != p[0]) ||    // Invalid packet; Not i3?
+            (recv_len < TCP_I3_HEADER_SIZE)) {
+            I3_PRINT_INFO1(I3_INFO_LEVEL_WARNING,
+                           "Invalid i3 tcp header on fd %d\n", fd);
+            return -1;
+        }
+        pkt_size = nhgets(p + 1);
+        if (len < pkt_size) {   // Invalid size
+            I3_PRINT_INFO2(I3_INFO_LEVEL_WARNING,
+                           "Invalid i3 tcp packet size %d (on fd %d)\n",
+                           pkt_size, fd);
+            return -1;
+        }
+
+        while (pkt_size > 0 && num_attempts++ < MAX_ATTEMPTS) {
+            recv_len        = recv(fd, p, pkt_size, 0);
+            total_recv_len += recv_len;
+            pkt_size       -= recv_len;
+            p              += recv_len;
+        }
+    }
+
+    /* Hack! */
+    if (pkt_size > 0) {
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "Still some more bytes to be 
received, quitting!\n");
+        return -1;
+    } else {
+        return total_recv_len;
+    }
+}

=== modified file 'i3/i3/i3_tcp_fns.h'
--- i3/i3/i3_tcp_fns.h  2009-12-11 22:49:11 +0000
+++ i3/i3/i3_tcp_fns.h  2010-02-11 11:49:47 +0000
@@ -1,14 +1,14 @@
-#ifndef _I3_TCP_FNS_H
-#define _I3_TCP_FNS_H
-#include "../utils/netwrap.h"
-
-/*************************************************************
- *  Packet formats for TCP packets, pack/unpack
- ************************************************************/
-/* Header = [ 1 byte: MAGIC | 2 bytes (packet length) ] */
-#define TCP_I3_HEADER_SIZE 3
-#define TCP_I3_HEADER_MAGIC 0x42
-int send_tcp(char *p, int len, nw_skt_t fd);
-int recv_tcp(char *p, int len, nw_skt_t fd);
-
-#endif
+#ifndef _I3_TCP_FNS_H
+#define _I3_TCP_FNS_H
+#include "../utils/netwrap.h"
+
+/*************************************************************
+ *  Packet formats for TCP packets, pack/unpack
+ ************************************************************/
+/* Header = [ 1 byte: MAGIC | 2 bytes (packet length) ] */
+#define TCP_I3_HEADER_SIZE 3
+#define TCP_I3_HEADER_MAGIC 0x42
+int send_tcp(char *p, int len, nw_skt_t fd);
+int recv_tcp(char *p, int len, nw_skt_t fd);
+
+#endif

=== modified file 'i3/i3/i3_trigger.c'
--- i3/i3/i3_trigger.c  2009-12-11 22:49:11 +0000
+++ i3/i3/i3_trigger.c  2010-02-11 11:49:47 +0000
@@ -1,577 +1,573 @@
-/***************************************************************************
-                          i3_trigger.c  -  description
-                             -------------------
-    begin                : Nov 18 2002
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#include "i3.h"
-#include "i3_fun.h"
-#include "i3_debug.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "../aeshash/aes.h"
-
-
-/***************************************************************************
- *  alloc_i3_trigger - allocate trigger data structure
- *
- *  return:
- *    pointer to the allocated data structure 
- ***************************************************************************/
-
-i3_trigger *alloc_i3_trigger()
-{
-  i3_trigger *trigger;
-
-  /* XXX: just simply call alloc for now; preallocate a pool of buffers 
-     in the future */
-  trigger = (i3_trigger *)calloc(1, sizeof(i3_trigger));
-  trigger->flags = 0;
-  trigger->tb = NULL;
-  
-  if (trigger) 
-    return trigger;
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,"alloc_i3_trigger: memory allocation 
error.\n");
-  return NULL;
-}
-
-
-/***************************************************************************
- *  init_i3_trigger - initialize trigger fields
- *
- *  input:
- *    t - trigger to be initialized
- *    prefix_len - prefix length
- *    id - trigger ID
- *    to - pointer to the address where packets matching "id"
- *         are forwarded (this data structure is not copied; don't
- *         free it after calling the function)
- *
- *  note:
- *    the nonce field is updated separately; see update_nonce() function
- ***************************************************************************/
-
-void init_i3_trigger(i3_trigger *t, ID *id, uint16_t prefix_len,
-                    i3_addr *to, Key *key, uint8_t flags)
-{
-  t->flags = flags;
-  memcpy((char *)&t->id.x, id->x, sizeof(ID));
-  t->prefix_len = prefix_len;
-  t->to = to;
-  if (key) {
-      memcpy(t->key.x, key->x, KEY_LEN);
-  }
-}
-
-/***************************************************************************
- *  free_i3_trigger - free trigger data structure
- *
- *  input:
- *    trigger to be freed
- *
- ***************************************************************************/
-
-void free_i3_trigger(i3_trigger *trigger)
-{
-  /* XXX: just simply call free for now ... */
-  if (trigger->to)
-    free_i3_addr(trigger->to);
-  if (trigger->tb)
-    free_token_bucket(trigger->tb);
-  free(trigger);
-}
-
-
-
-/***************************************************************************
- *  duplicate_i3_trigger - create a replica of trigger t
- *
- *  input:
- *    t - trigger to be duplicated
- *
- *  return:
- *    t's replica
- ***************************************************************************/
-
-i3_trigger *duplicate_i3_trigger(i3_trigger *t)
-{
-  i3_trigger *tnew = alloc_i3_trigger();
-
-  tnew->flags = t->flags;
-  memcpy((char *)&tnew->id.x, (char *)&t->id.x, sizeof(ID));
-  tnew->prefix_len = t->prefix_len;
-  memcpy((char *)tnew->nonce, (char *)t->nonce, NONCE_LEN);
-  tnew->to = duplicate_i3_addr(t->to);
-  memcpy(tnew->key.x, t->key.x, KEY_LEN);
-  if (t->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
-    assert(t->tb);
-    tnew->tb = duplicate_token_bucket(t->tb);
-  }
-  return tnew;
-}
-
-
-
-
-/***************************************************************************
- *  pack_i3_trigger - convert a trigger data structure in packet format
- *
- *  input:
- *    p - address of the buffer where the trigger is to be stored in 
- *        packet format (pre-allocated)
- *    trigger - trigger to be converted in packet format
- *    
- *  output:
- *    length - length of the trigger in packet format
- ***************************************************************************/
-
-void pack_i3_trigger(char *p, i3_trigger *trigger, 
-                    unsigned short *length)
-{
-  unsigned short len = 0, temp;
-
-  *p = trigger->flags;
-  p += sizeof(char);
-  *length = sizeof(char);
-
-  memcpy(p, &trigger->id.x, sizeof(ID));
-  p += sizeof(ID); 
-  *length += sizeof(ID);
-
-  temp = htons(trigger->prefix_len);
-  memcpy(p, &temp, sizeof(uint16_t));
-  p += sizeof(uint16_t);
-  *length += sizeof(uint16_t);
-
-  memcpy(p, trigger->nonce, NONCE_LEN);
-  p += NONCE_LEN; 
-  *length += NONCE_LEN;
-
-  pack_i3_addr(p, trigger->to, &len);
-  *length += len;
-  p += len;
-
-  if (I3_ADDR_TYPE_STACK != trigger->to->type) {
-    memcpy(p, trigger->key.x, KEY_LEN);
-    *length += KEY_LEN;
-    p += KEY_LEN;
-  }
-
-  if (trigger->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
-    assert(trigger->tb);
-    pack_token_bucket(p, trigger->tb, &len);
-    *length += len;
-    p += len;
-  }
-}
-
-unsigned short get_i3_trigger_len(i3_trigger *trigger) 
-{
-  unsigned short length;
-
-  length = sizeof(char) + sizeof(ID); // flags + id
-
-  length += sizeof(uint16_t); /* prefix length */
-
-  length += NONCE_LEN;
-
-  length += get_i3_addr_len(trigger->to);
-
-  if (I3_ADDR_TYPE_STACK != trigger->to->type) {
-      length += KEY_LEN;
-  }
-
-  if (trigger->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
-      assert(trigger->tb);
-      length += get_token_bucket_len();
-  }
-
-  return length;
-}
-
-
-/***************************************************************************
- *  unpack_i3_trigger - allocate an i3_trigger data structure
- *                      and copy info from packet into it
- *
- *  input:
- *    p - address where trigger is stored in packet format
- *    
- *  output:
- *    length - length of the trigger info in packet format
- *
- ***************************************************************************/
-
-i3_trigger *unpack_i3_trigger(char *p, unsigned short *length)
-{
-  i3_trigger *trigger = alloc_i3_trigger();
-  unsigned short len;
-
-  trigger->flags = *p;
-   
-  *length = sizeof(char);
-  p += sizeof(char);
-
-  memcpy(&trigger->id.x, p, sizeof(ID));
-  *length += sizeof(ID); 
-  p += sizeof(ID);
-
-  trigger->prefix_len = ntohs(*((uint16_t *)p));
-  *length += sizeof(uint16_t);
-  p += sizeof(uint16_t);
-
-  memcpy(&trigger->nonce, p, NONCE_LEN);
-  *length += NONCE_LEN; 
-  p += NONCE_LEN;
-
-  trigger->to = unpack_i3_addr(p, &len);
-  *length += len;
-  p += len;
-
-  if (I3_ADDR_TYPE_STACK != trigger->to->type) {
-      memcpy(trigger->key.x, p, KEY_LEN);
-      *length += KEY_LEN;
-      p += KEY_LEN;
-  }
-
-  if (trigger->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
-      trigger->tb = unpack_token_bucket(p, &len);
-      *length += len;
-      p += len;
-  }
-  
-   return trigger;
-}
-
-
-/***************************************************************************
- *  check_i3_trigger - check whether i3 trigger is well-formed
- *
- *  input:
- *    p - address where trigger is stored in packet format
- *
- *  return:
- *    error code; FALSE if no error
- *
- *  output:
- *    length - length of the trigger info in packet format
- *
- ***************************************************************************/
-
-int check_i3_trigger(char *p, unsigned short *length)
-{
-  unsigned short len;
-  char type, flags;
-  int rc;
-
-  flags = p[0];
-  *length = sizeof(char); /* Flags */
-  p += sizeof(char);
-
-  *length += sizeof(ID); /* ID */
-  p += sizeof(ID);
-
-  *length += sizeof(uint16_t); /* prefix len */
-  p += sizeof(uint16_t);
-
-  *length += NONCE_LEN;  /* nonce */
-  p += NONCE_LEN;
-
-  if ((rc = check_i3_addr(p, &len, &type)) != FALSE)
-    return rc;
-
-  *length += len;
-
-  if (I3_ADDR_TYPE_STACK != type) 
-    *length += KEY_LEN;
-  
-  if (flags & I3_TRIGGER_FLAG_RATE_LIMIT) 
-    *length += get_token_bucket_len();
-
-  return FALSE;
-}
-
-
-
-/***************************************************************************
- *  trigger_equal - compare two triggers
- *
- *  input:
- *    t1, t2 - triggers to be compared
- *    
- *  return:
- *    TRUE, if triggers are identical; FALSE, if they are not
- *
- *  note:
- *    ingnore the "id" field since this function is used to compare 
- *    triggers with the same ids; also ignore the "nonce" field as
- *    the nonce is checked when the trigger is inserted
- *
- ***************************************************************************/
-
-int trigger_equal(i3_trigger *t1, i3_trigger *t2)
-{
-  if (memcmp(t1->id.x, t2->id.x, ID_LEN)) {
-      return FALSE;
-  }
-//   if (memcmp(t1->key.x, t2->key.x, KEY_LEN))
-//       return FALSE;
-  return addr_equal(t1->to, t2->to);
-}
-
-
-/***************************************************************************
- *  update_nonce - compute nonce of a given trigger
- *
- *  input:
- *    t - given trigger
- *
- *  note:
- *    the algorithm to compute a nonce is trival now; it will be
- *    modified in the future
- ***************************************************************************/
-
-void update_nonce(i3_trigger *t)
-{
-  compute_nonce(t->nonce, t->to);
-}
-
-/***************************************************************************
- *  check_nonce - check the nonce of a given trigger
- *
- *  input:
- *    t - given trigger
- *
- *  note:
- *    obviously, this function has to implement the same algorithm to
- *    compute the nonce as "update_nonce"! So if the algorithm is changed
- *    this needs to be done in both "check_nonce" and "update_nonce" 
- *    functions
- *
- ***************************************************************************/
-
-int check_nonce(i3_trigger *t)
-{
-  char nonce[NONCE_LEN];
-
-  compute_nonce(nonce, t->to);
-  
-  if (!memcmp(nonce, t->nonce, NONCE_LEN))
-    return TRUE;
-  else
-    return FALSE;
-}
-
-  
-/*******************************************************
- ** print i3_trigger -- this is for debuging proposes **
- *******************************************************/
-
-void printf_i3_trigger(i3_trigger *trigger, int indent)
-{
-  int i;
-  char buf[INDENT_BUF_LEN];
-
-  memset(buf, ' ', indent);
-  buf[indent] = 0;
-
-  printf("%s flags = %x\n", buf, trigger->flags);
-  printf_i3_id(&trigger->id, indent + 2);
-  printf("%s  prefix_len: %d\n", buf, trigger->prefix_len);
-  printf("%s nonce = ", buf);
-  for (i=0; i < NONCE_LEN; i++)
-    printf("%d.", trigger->nonce[i]);
-  printf("\n");
-  printf_i3_addr(trigger->to, indent + 2);
-  if (trigger->flags & I3_TRIGGER_FLAG_RATE_LIMIT) 
-    printf_token_bucket(trigger->tb, indent + 2);
-}
-
-/********************************************************
- *
- * Constrained triggers:
- * --------------------
- *
- *  T = (x, y), where {x,y} E I3_Addr
- *  Also, x = [x.prefix | x.key | x.suffix]
- *
- *  l-constraint: 
- *     if y E ID
- *             x.key = h_l(y)
- *     else if y E IP Addr
- *             x.key = h_l(y.key)
- *             
- *  r-constraint:
- *     y.key = h_r(x)
- *
- *
- * For generating a 256->128 hash fn from a 128->128 hash function,
- * foll is done:
- *
- *     x (256 bits) = [x1 | x2] where x1 and x2 are 128 bits long
- *
- *     y1 = First 64 bits of h(x1)
- *     y2 = Last 64 bits of h(x2)
- *
- *     Y = H(x) = h( y1|y2 )
- *
- ********************************************************/
-
-/********************************************************
- * Generate constraints 
- *******************************************************/
-typedef void (*AesHash) (const unsigned char in[], unsigned char out[]);
-static const AesHash aeshash[2] = {&aeshash_l, &aeshash_r};
-
-void printf_i3_key(uint8_t *t, int indent)
-{
-    char buf[INDENT_BUF_LEN];
-    uint i;
-    
-    memset(buf, ' ', INDENT_BUF_LEN);
-    buf[indent] = 0;
-    
-    printf("%s key: ", buf);
-    for (i = 0; i < KEY_LEN; i++)
-       printf("%02x", (int)(t[i]));
-    printf("\n");
-}
-
-void generate_constraint_id(ID *id, Key *key, int type)
-{
-    Key k1, k2;
-    
-    aeshash[type](id->x, k1.x);
-    aeshash[type](id->x + ID_LEN/2, k2.x);
-
-    memcpy(k1.x + KEY_LEN/2, k2.x + KEY_LEN/2, KEY_LEN/2);
-
-    aeshash[type](k1.x, key->x);
-}
-
-void generate_l_constraint_addr(Key *rkey, Key *lkey)
-{
-    aeshash_l(rkey->x, lkey->x);
-}   
-
-void generate_r_constraint_addr(Key *lkey, Key *rkey)
-{
-    aeshash_r(lkey->x, rkey->x); 
-}   
-
-
-void generate_l_constraint(i3_trigger *t, Key *key)
-{
-    if (I3_ADDR_TYPE_STACK == t->to->type)
-           generate_l_constraint_id(t->to->t.stack->ids, key);
-    else {
-           // printf("l-constr from key: ");
-           // printf_i3_key(t->key.x, 2);
-           generate_l_constraint_addr(&t->key, key);
-    }
-}
-
-int is_constrained(ID *id, Key *key)
-{
-    int retval;
-    retval = (0 == memcmp(KEY_ID_PTR(id), key->x, KEY_LEN));
-
-    // printf("Required key: "); printf_i3_key(key->x, 2);
-    // printf("Obtained key: "); printf_i3_key(KEY_ID_PTR(id), 2);
-    
-    return retval;
-}
-
-/*******************************************************
- * Check constraints
- *  -- called by server when trigger insert is attempted 
- *******************************************************/
-int check_constraint(i3_trigger *t)
-{
-    Key key;
-    char type;
-
-    type = get_id_type (&(t->id));
-   
-    /*
-    if (I3_ID_TYPE_UNCONSTRAINED == type) {
-        //Unconstrained ids require no checking.
-        printf ("\n\nUnconstrained trigger being checked\n\n");
-        return 1;
-    }
-
-    */
-    
-    /* l-constraint is ok for any ID type (ie. public/private) */
-    generate_l_constraint(t, &key);
-    if (is_constrained(&(t->id), &key)) {
-           return 1;
-    }
-
-    /* r-constraint is ok only for private IDs */
-    type = get_id_type(&(t->id));
-    if (I3_ID_TYPE_PRIVATE != type) {
-           return 0;
-    }
-   
-    /* check for r-constraint */
-    generate_r_constraint(&t->id, &key);
-    if (I3_ADDR_TYPE_STACK == t->to->type) {
-        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,"c1 -- check_constraint\n");
-           if (is_constrained(t->to->t.stack->ids, &key)) {
-               return 1;
-           }
-    } else {
-           if (0 == memcmp(t->key.x, key.x, KEY_LEN)) {
-               return 1;
-           }
-    }
-
-    return 0;
-}
-
-/*******************************************************
- * set the key in the client data structures
- ******************************************************/
-void set_key_id(ID *id, Key *key)
-{
-    memcpy(KEY_ID_PTR(id), key->x, KEY_LEN);
-}
-
-void set_key_addr(Key *dst, Key *src)
-{
-    memcpy(dst, src, KEY_LEN);
-}
-
-
-/*******************************************************
- * Set key in path
- * Parameters: - id array
- *             - array length
- *             - key of the first/last ID depending on l/r-constraint
- *             - return key ie. of the other end of path
- ******************************************************/
-void l_constrain_path(ID *id, int path_len)
-{
-    Key key;
-    int i; 
-
-    for (i = path_len - 1; i > 0; i--) {
-       generate_l_constraint_id(&(id[i]), &key);
-       set_key_id(&(id[i-1]), &key);
-    }
-}
-
-void r_constrain_path(ID *id, int path_len)
-{
-    Key key;
-    int i; 
-
-    for (i = 0; i < path_len - 1; i++) {
-       generate_r_constraint_id(&(id[i]), &key);
-       set_key_id(&(id[i+1]), &key);
-    }
-}
+/***************************************************************************
+*                         i3_trigger.c  -  description
+*                            -------------------
+*   begin                : Nov 18 2002
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#include "i3.h"
+#include "i3_fun.h"
+#include "i3_debug.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../aeshash/aes.h"
+
+
+/***************************************************************************
+*  alloc_i3_trigger - allocate trigger data structure
+*
+*  return:
+*    pointer to the allocated data structure
+***************************************************************************/
+
+i3_trigger *alloc_i3_trigger()
+{
+    i3_trigger *trigger;
+
+    /* XXX: just simply call alloc for now; preallocate a pool of buffers
+     * in the future */
+    trigger        = (i3_trigger *) calloc(1, sizeof(i3_trigger));
+    trigger->flags = 0;
+    trigger->tb    = NULL;
+
+    if (trigger) {
+        return trigger;
+    }
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "alloc_i3_trigger: memory 
allocation error.\n");
+    return NULL;
+}
+
+/***************************************************************************
+*  init_i3_trigger - initialize trigger fields
+*
+*  input:
+*    t - trigger to be initialized
+*    prefix_len - prefix length
+*    id - trigger ID
+*    to - pointer to the address where packets matching "id"
+*         are forwarded (this data structure is not copied; don't
+*         free it after calling the function)
+*
+*  note:
+*    the nonce field is updated separately; see update_nonce() function
+***************************************************************************/
+
+void init_i3_trigger(i3_trigger *t, ID *id, uint16_t prefix_len,
+                     i3_addr *to, Key *key, uint8_t flags)
+{
+    t->flags      = flags;
+    memcpy((char *) &t->id.x, id->x, sizeof(ID));
+    t->prefix_len = prefix_len;
+    t->to         = to;
+    if (key) {
+        memcpy(t->key.x, key->x, KEY_LEN);
+    }
+}
+
+/***************************************************************************
+*  free_i3_trigger - free trigger data structure
+*
+*  input:
+*    trigger to be freed
+*
+***************************************************************************/
+
+void free_i3_trigger(i3_trigger *trigger)
+{
+    /* XXX: just simply call free for now ... */
+    if (trigger->to) {
+        free_i3_addr(trigger->to);
+    }
+    if (trigger->tb) {
+        free_token_bucket(trigger->tb);
+    }
+    free(trigger);
+}
+
+/***************************************************************************
+*  duplicate_i3_trigger - create a replica of trigger t
+*
+*  input:
+*    t - trigger to be duplicated
+*
+*  return:
+*    t's replica
+***************************************************************************/
+
+i3_trigger *duplicate_i3_trigger(i3_trigger *t)
+{
+    i3_trigger *tnew = alloc_i3_trigger();
+
+    tnew->flags      = t->flags;
+    memcpy((char *) &tnew->id.x, (char *) &t->id.x, sizeof(ID));
+    tnew->prefix_len = t->prefix_len;
+    memcpy((char *) tnew->nonce, (char *) t->nonce, NONCE_LEN);
+    tnew->to         = duplicate_i3_addr(t->to);
+    memcpy(tnew->key.x, t->key.x, KEY_LEN);
+    if (t->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
+        assert(t->tb);
+        tnew->tb = duplicate_token_bucket(t->tb);
+    }
+    return tnew;
+}
+
+/***************************************************************************
+*  pack_i3_trigger - convert a trigger data structure in packet format
+*
+*  input:
+*    p - address of the buffer where the trigger is to be stored in
+*        packet format (pre-allocated)
+*    trigger - trigger to be converted in packet format
+*
+*  output:
+*    length - length of the trigger in packet format
+***************************************************************************/
+
+void pack_i3_trigger(char *p, i3_trigger *trigger,
+                     unsigned short *length)
+{
+    unsigned short len = 0, temp;
+
+    *p       = trigger->flags;
+    p       += sizeof(char);
+    *length  = sizeof(char);
+
+    memcpy(p, &trigger->id.x, sizeof(ID));
+    p       += sizeof(ID);
+    *length += sizeof(ID);
+
+    temp     = htons(trigger->prefix_len);
+    memcpy(p, &temp, sizeof(uint16_t));
+    p       += sizeof(uint16_t);
+    *length += sizeof(uint16_t);
+
+    memcpy(p, trigger->nonce, NONCE_LEN);
+    p       += NONCE_LEN;
+    *length += NONCE_LEN;
+
+    pack_i3_addr(p, trigger->to, &len);
+    *length += len;
+    p       += len;
+
+    if (I3_ADDR_TYPE_STACK != trigger->to->type) {
+        memcpy(p, trigger->key.x, KEY_LEN);
+        *length += KEY_LEN;
+        p       += KEY_LEN;
+    }
+
+    if (trigger->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
+        assert(trigger->tb);
+        pack_token_bucket(p, trigger->tb, &len);
+        *length += len;
+        p       += len;
+    }
+}
+
+unsigned short get_i3_trigger_len(i3_trigger *trigger)
+{
+    unsigned short length;
+
+    length  = sizeof(char) + sizeof(ID); // flags + id
+
+    length += sizeof(uint16_t); /* prefix length */
+
+    length += NONCE_LEN;
+
+    length += get_i3_addr_len(trigger->to);
+
+    if (I3_ADDR_TYPE_STACK != trigger->to->type) {
+        length += KEY_LEN;
+    }
+
+    if (trigger->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
+        assert(trigger->tb);
+        length += get_token_bucket_len();
+    }
+
+    return length;
+}
+
+/***************************************************************************
+*  unpack_i3_trigger - allocate an i3_trigger data structure
+*                      and copy info from packet into it
+*
+*  input:
+*    p - address where trigger is stored in packet format
+*
+*  output:
+*    length - length of the trigger info in packet format
+*
+***************************************************************************/
+
+i3_trigger *unpack_i3_trigger(char *p, unsigned short *length)
+{
+    i3_trigger *trigger = alloc_i3_trigger();
+    unsigned short len;
+
+    trigger->flags      = *p;
+
+    *length             = sizeof(char);
+    p                  += sizeof(char);
+
+    memcpy(&trigger->id.x, p, sizeof(ID));
+    *length            += sizeof(ID);
+    p                  += sizeof(ID);
+
+    trigger->prefix_len = ntohs(*((uint16_t *) p));
+    *length            += sizeof(uint16_t);
+    p                  += sizeof(uint16_t);
+
+    memcpy(&trigger->nonce, p, NONCE_LEN);
+    *length            += NONCE_LEN;
+    p                  += NONCE_LEN;
+
+    trigger->to         = unpack_i3_addr(p, &len);
+    *length            += len;
+    p                  += len;
+
+    if (I3_ADDR_TYPE_STACK != trigger->to->type) {
+        memcpy(trigger->key.x, p, KEY_LEN);
+        *length += KEY_LEN;
+        p       += KEY_LEN;
+    }
+
+    if (trigger->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
+        trigger->tb = unpack_token_bucket(p, &len);
+        *length    += len;
+        p          += len;
+    }
+
+    return trigger;
+}
+
+/***************************************************************************
+*  check_i3_trigger - check whether i3 trigger is well-formed
+*
+*  input:
+*    p - address where trigger is stored in packet format
+*
+*  return:
+*    error code; FALSE if no error
+*
+*  output:
+*    length - length of the trigger info in packet format
+*
+***************************************************************************/
+
+int check_i3_trigger(char *p, unsigned short *length)
+{
+    unsigned short len;
+    char type, flags;
+    int rc;
+
+    flags    = p[0];
+    *length  = sizeof(char); /* Flags */
+    p       += sizeof(char);
+
+    *length += sizeof(ID); /* ID */
+    p       += sizeof(ID);
+
+    *length += sizeof(uint16_t); /* prefix len */
+    p       += sizeof(uint16_t);
+
+    *length += NONCE_LEN; /* nonce */
+    p       += NONCE_LEN;
+
+    if ((rc = check_i3_addr(p, &len, &type)) != FALSE) {
+        return rc;
+    }
+
+    *length += len;
+
+    if (I3_ADDR_TYPE_STACK != type) {
+        *length += KEY_LEN;
+    }
+
+    if (flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
+        *length += get_token_bucket_len();
+    }
+
+    return FALSE;
+}
+
+/***************************************************************************
+*  trigger_equal - compare two triggers
+*
+*  input:
+*    t1, t2 - triggers to be compared
+*
+*  return:
+*    TRUE, if triggers are identical; FALSE, if they are not
+*
+*  note:
+*    ingnore the "id" field since this function is used to compare
+*    triggers with the same ids; also ignore the "nonce" field as
+*    the nonce is checked when the trigger is inserted
+*
+***************************************************************************/
+
+int trigger_equal(i3_trigger *t1, i3_trigger *t2)
+{
+    if (memcmp(t1->id.x, t2->id.x, ID_LEN)) {
+        return FALSE;
+    }
+//   if (memcmp(t1->key.x, t2->key.x, KEY_LEN))
+//       return FALSE;
+    return addr_equal(t1->to, t2->to);
+}
+
+/***************************************************************************
+*  update_nonce - compute nonce of a given trigger
+*
+*  input:
+*    t - given trigger
+*
+*  note:
+*    the algorithm to compute a nonce is trival now; it will be
+*    modified in the future
+***************************************************************************/
+
+void update_nonce(i3_trigger *t)
+{
+    compute_nonce(t->nonce, t->to);
+}
+
+/***************************************************************************
+*  check_nonce - check the nonce of a given trigger
+*
+*  input:
+*    t - given trigger
+*
+*  note:
+*    obviously, this function has to implement the same algorithm to
+*    compute the nonce as "update_nonce"! So if the algorithm is changed
+*    this needs to be done in both "check_nonce" and "update_nonce"
+*    functions
+*
+***************************************************************************/
+
+int check_nonce(i3_trigger *t)
+{
+    char nonce[NONCE_LEN];
+
+    compute_nonce(nonce, t->to);
+
+    if (!memcmp(nonce, t->nonce, NONCE_LEN)) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+/*******************************************************
+** print i3_trigger -- this is for debuging proposes **
+*******************************************************/
+
+void printf_i3_trigger(i3_trigger *trigger, int indent)
+{
+    int i;
+    char buf[INDENT_BUF_LEN];
+
+    memset(buf, ' ', indent);
+    buf[indent] = 0;
+
+    printf("%s flags = %x\n", buf, trigger->flags);
+    printf_i3_id(&trigger->id, indent + 2);
+    printf("%s  prefix_len: %d\n", buf, trigger->prefix_len);
+    printf("%s nonce = ", buf);
+    for (i = 0; i < NONCE_LEN; i++) {
+        printf("%d.", trigger->nonce[i]);
+    }
+    printf("\n");
+    printf_i3_addr(trigger->to, indent + 2);
+    if (trigger->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
+        printf_token_bucket(trigger->tb, indent + 2);
+    }
+}
+
+/********************************************************
+*
+* Constrained triggers:
+* --------------------
+*
+*  T = (x, y), where {x,y} E I3_Addr
+*  Also, x = [x.prefix | x.key | x.suffix]
+*
+*  l-constraint:
+*   if y E ID
+*       x.key = h_l(y)
+*   else if y E IP Addr
+*       x.key = h_l(y.key)
+*
+*  r-constraint:
+*   y.key = h_r(x)
+*
+*
+* For generating a 256->128 hash fn from a 128->128 hash function,
+* foll is done:
+*
+*   x (256 bits) = [x1 | x2] where x1 and x2 are 128 bits long
+*
+*   y1 = First 64 bits of h(x1)
+*   y2 = Last 64 bits of h(x2)
+*
+*   Y = H(x) = h( y1|y2 )
+*
+********************************************************/
+
+/********************************************************
+ * Generate constraints
+ *******************************************************/
+typedef void (*AesHash)(const unsigned char in[], unsigned char out[]);
+static const AesHash aeshash[2] = {&aeshash_l, &aeshash_r};
+
+void printf_i3_key(uint8_t *t, int indent)
+{
+    char buf[INDENT_BUF_LEN];
+    uint i;
+
+    memset(buf, ' ', INDENT_BUF_LEN);
+    buf[indent] = 0;
+
+    printf("%s key: ", buf);
+    for (i = 0; i < KEY_LEN; i++) {
+        printf("%02x", (int) (t[i]));
+    }
+    printf("\n");
+}
+
+void generate_constraint_id(ID *id, Key *key, int type)
+{
+    Key k1, k2;
+
+    aeshash[type](id->x, k1.x);
+    aeshash[type](id->x + ID_LEN / 2, k2.x);
+
+    memcpy(k1.x + KEY_LEN / 2, k2.x + KEY_LEN / 2, KEY_LEN / 2);
+
+    aeshash[type](k1.x, key->x);
+}
+
+void generate_l_constraint_addr(Key *rkey, Key *lkey)
+{
+    aeshash_l(rkey->x, lkey->x);
+}
+
+void generate_r_constraint_addr(Key *lkey, Key *rkey)
+{
+    aeshash_r(lkey->x, rkey->x);
+}
+
+void generate_l_constraint(i3_trigger *t, Key *key)
+{
+    if (I3_ADDR_TYPE_STACK == t->to->type) {
+        generate_l_constraint_id(t->to->t.stack->ids, key);
+    } else {
+        // printf("l-constr from key: ");
+        // printf_i3_key(t->key.x, 2);
+        generate_l_constraint_addr(&t->key, key);
+    }
+}
+
+int is_constrained(ID *id, Key *key)
+{
+    int retval;
+    retval = (0 == memcmp(KEY_ID_PTR(id), key->x, KEY_LEN));
+
+    // printf("Required key: "); printf_i3_key(key->x, 2);
+    // printf("Obtained key: "); printf_i3_key(KEY_ID_PTR(id), 2);
+
+    return retval;
+}
+
+/*******************************************************
+* Check constraints
+*  -- called by server when trigger insert is attempted
+*******************************************************/
+int check_constraint(i3_trigger *t)
+{
+    Key key;
+    char type;
+
+    type = get_id_type(&(t->id));
+
+    /*
+     * if (I3_ID_TYPE_UNCONSTRAINED == type) {
+     *  //Unconstrained ids require no checking.
+     *  printf ("\n\nUnconstrained trigger being checked\n\n");
+     *  return 1;
+     * }
+     *
+     */
+
+    /* l-constraint is ok for any ID type (ie. public/private) */
+    generate_l_constraint(t, &key);
+    if (is_constrained(&(t->id), &key)) {
+        return 1;
+    }
+
+    /* r-constraint is ok only for private IDs */
+    type = get_id_type(&(t->id));
+    if (I3_ID_TYPE_PRIVATE != type) {
+        return 0;
+    }
+
+    /* check for r-constraint */
+    generate_r_constraint(&t->id, &key);
+    if (I3_ADDR_TYPE_STACK == t->to->type) {
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "c1 -- check_constraint\n");
+        if (is_constrained(t->to->t.stack->ids, &key)) {
+            return 1;
+        }
+    } else {
+        if (0 == memcmp(t->key.x, key.x, KEY_LEN)) {
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+/*******************************************************
+ * set the key in the client data structures
+ ******************************************************/
+void set_key_id(ID *id, Key *key)
+{
+    memcpy(KEY_ID_PTR(id), key->x, KEY_LEN);
+}
+
+void set_key_addr(Key *dst, Key *src)
+{
+    memcpy(dst, src, KEY_LEN);
+}
+
+/*******************************************************
+ * Set key in path
+ * Parameters:    - id array
+ *      - array length
+ *      - key of the first/last ID depending on l/r-constraint
+ *      - return key ie. of the other end of path
+ ******************************************************/
+void l_constrain_path(ID *id, int path_len)
+{
+    Key key;
+    int i;
+
+    for (i = path_len - 1; i > 0; i--) {
+        generate_l_constraint_id(&(id[i]), &key);
+        set_key_id(&(id[i - 1]), &key);
+    }
+}
+
+void r_constrain_path(ID *id, int path_len)
+{
+    Key key;
+    int i;
+
+    for (i = 0; i < path_len - 1; i++) {
+        generate_r_constraint_id(&(id[i]), &key);
+        set_key_id(&(id[i + 1]), &key);
+    }
+}

=== modified file 'i3/i3/i3_trigger.h'
--- i3/i3/i3_trigger.h  2010-01-06 22:17:32 +0000
+++ i3/i3/i3_trigger.h  2010-02-11 11:49:47 +0000
@@ -1,42 +1,42 @@
-/***************************************************************************
-                          i3_trigger.h  -  description
-                             -------------------
-    begin                : Fre Jun 20 2003
-    copyright            : (C) 2003 by klaus
-    email                : wehrle@xxxxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef I3_TRIGGER_H
-#define I3_TRIGGER_H
-
- 
-/* functions implemented in i3_trigger.c */
-i3_trigger *alloc_i3_trigger(void);
-void init_i3_trigger(i3_trigger *t, ID *id, uint16_t prefix_len, 
-                    struct i3_addr *to, Key *key, uint8_t flags);
-void free_i3_trigger(i3_trigger *trigger);
-void pack_i3_trigger(char *p, i3_trigger *trigger, unsigned short *length);
-unsigned short get_i3_trigger_len(i3_trigger *trigger);
-i3_trigger *unpack_i3_trigger(char *p, unsigned short *length);
-int check_i3_trigger(char *p, unsigned short *length);
-int trigger_equal(i3_trigger *t1, i3_trigger *t2);
-void printf_i3_trigger(i3_trigger *trigger, int indent);
-void update_nonce(i3_trigger *t);
-int check_nonce(i3_trigger *t);
-i3_trigger *duplicate_i3_trigger(i3_trigger *t);
-
-void generate_constraint_id(ID *id, Key *key, int type);
-#define generate_r_constraint_id(id, key) generate_constraint_id(id, key, 
R_CONSTRAINT)
-#define generate_r_constraint(id, key) generate_constraint_id(id, key, 
R_CONSTRAINT)
-#define generate_l_constraint_id(id, key) generate_constraint_id(id, key, 
L_CONSTRAINT)
-void generate_l_constraint_addr(Key *rkey, Key *lkey);
-int check_constraint(i3_trigger *t);
-void set_key_id(ID *id, Key *key);
-void set_key_addr(Key *dst, Key *src);
-
-void l_constrain_path(ID *id, int path_len);
-void r_constrain_path(ID *id, int path_len);
-
-void printf_i3_key(uint8_t *k,int indent);
-
-#endif
+/***************************************************************************
+*                         i3_trigger.h  -  description
+*                            -------------------
+*   begin                : Fre Jun 20 2003
+*   copyright            : (C) 2003 by klaus
+*   email                : wehrle@xxxxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef I3_TRIGGER_H
+#define I3_TRIGGER_H
+
+
+/* functions implemented in i3_trigger.c */
+i3_trigger *alloc_i3_trigger(void);
+void init_i3_trigger(i3_trigger *t, ID *id, uint16_t prefix_len,
+                     struct i3_addr *to, Key *key, uint8_t flags);
+void free_i3_trigger(i3_trigger *trigger);
+void pack_i3_trigger(char *p, i3_trigger *trigger, unsigned short *length);
+unsigned short get_i3_trigger_len(i3_trigger *trigger);
+i3_trigger *unpack_i3_trigger(char *p, unsigned short *length);
+int check_i3_trigger(char *p, unsigned short *length);
+int trigger_equal(i3_trigger *t1, i3_trigger *t2);
+void printf_i3_trigger(i3_trigger *trigger, int indent);
+void update_nonce(i3_trigger *t);
+int check_nonce(i3_trigger *t);
+i3_trigger *duplicate_i3_trigger(i3_trigger *t);
+
+void generate_constraint_id(ID *id, Key *key, int type);
+#define generate_r_constraint_id(id, key) generate_constraint_id(id, key, 
R_CONSTRAINT)
+#define generate_r_constraint(id, key) generate_constraint_id(id, key, 
R_CONSTRAINT)
+#define generate_l_constraint_id(id, key) generate_constraint_id(id, key, 
L_CONSTRAINT)
+void generate_l_constraint_addr(Key *rkey, Key *lkey);
+int check_constraint(i3_trigger *t);
+void set_key_id(ID *id, Key *key);
+void set_key_addr(Key *dst, Key *src);
+
+void l_constrain_path(ID *id, int path_len);
+void r_constrain_path(ID *id, int path_len);
+
+void printf_i3_key(uint8_t *k, int indent);
+
+#endif

=== modified file 'i3/i3/i3_utils.c'
--- i3/i3/i3_utils.c    2009-12-11 22:49:11 +0000
+++ i3/i3/i3_utils.c    2010-02-11 11:49:47 +0000
@@ -1,33 +1,34 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>    
-
-#define MAXLINE     4096
-
-
-/*static*/ void err_doit(int errnoflag, const char *fmt, va_list ap)
-{
-  int     errno_save;
-  char    buf[MAXLINE];
-  
-  errno_save = errno;             /* value caller might want printed */
-  vsprintf(buf, fmt, ap);
-  if (errnoflag)
-    sprintf(buf+strlen(buf), ": %s", strerror(errno_save));
-  strcat(buf, "\n");
-  fflush(stdout);         /* in case stdout and stderr are the same */
-  fputs(buf, stderr);
-  fflush(NULL);           /* flushes all stdio output streams */
-}
-
-void err_sys(const char *fmt, ...)
-{
-  va_list         ap;
-  
-  va_start(ap, fmt);
-  err_doit(1, fmt, ap);
-  va_end(ap);
-  exit(1);
-}
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+#define MAXLINE     4096
+
+
+/*static*/ void err_doit(int errnoflag, const char *fmt, va_list ap)
+{
+    int errno_save;
+    char buf[MAXLINE];
+
+    errno_save = errno;           /* value caller might want printed */
+    vsprintf(buf, fmt, ap);
+    if (errnoflag) {
+        sprintf(buf + strlen(buf), ": %s", strerror(errno_save));
+    }
+    strcat(buf, "\n");
+    fflush(stdout);       /* in case stdout and stderr are the same */
+    fputs(buf, stderr);
+    fflush(NULL);         /* flushes all stdio output streams */
+}
+
+void err_sys(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    err_doit(1, fmt, ap);
+    va_end(ap);
+    exit(1);
+}

=== modified file 'i3/i3/i3_utils.h'
--- i3/i3/i3_utils.h    2009-12-11 22:49:11 +0000
+++ i3/i3/i3_utils.h    2010-02-11 11:49:47 +0000
@@ -1,21 +1,21 @@
-/***************************************************************************
-                          i3_utils.h  -  description
-                             -------------------
-    begin                : Sam Jun 21 2003
-    copyright            : (C) 2003 by klaus
-    email                : wehrle@xxxxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef I3_UTILS_H
-#define I3_UTILS_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-
-/*static*/ void err_doit(int errnoflag, const char *fmt, va_list ap);
-void err_sys(const char *fmt, ...);
-
-
-#endif //I3_UTILS_H
+/***************************************************************************
+*                         i3_utils.h  -  description
+*                            -------------------
+*   begin                : Sam Jun 21 2003
+*   copyright            : (C) 2003 by klaus
+*   email                : wehrle@xxxxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef I3_UTILS_H
+#define I3_UTILS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+/*static*/ void err_doit(int errnoflag, const char *fmt, va_list ap);
+void err_sys(const char *fmt, ...);
+
+
+#endif //I3_UTILS_H

=== modified file 'i3/i3/token_bucket.c'
--- i3/i3/token_bucket.c        2009-12-11 22:49:11 +0000
+++ i3/i3/token_bucket.c        2010-02-11 11:49:47 +0000
@@ -1,266 +1,257 @@
-/***************************************************************************
-                          token_bucket.c  -  description
-                             -------------------
-    begin                : Nov 20 2002
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#include "i3.h"
-#include "i3_fun.h"
-#include "i3_debug.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-/***************************************************************************
- *  alloc_token_bucket - allocate a token bucket data structure
- *
- *  return:
- *    pointer to the allocated token bucket
- ***************************************************************************/
-
-token_bucket *alloc_token_bucket()
-{
-  token_bucket *tb;
-
-  tb = (token_bucket *)calloc(1, sizeof(token_bucket));
-  if (tb) 
-    return tb;
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,
-             "alloc_token_bucket: memory allocation error.\n");
-  return NULL;
-}
-
-
-/***************************************************************************
- *  init_token_bucket - initialize token bucket's fields
- *
- *  return:
- *    pointer to the allocated token bucket 
- ***************************************************************************/
-
-void init_token_bucket(token_bucket *tb, uint8_t type,
-                      uint32_t depth, uint32_t r, uint32_t R)
-{
-  tb->type = type;
-  tb->depth = depth;
-  tb->r = r;
-  tb->R = R;
-}
-
-
-/***************************************************************************
- *  free_token_bucket - free tb data structure 
- *
- *  input:
- *    tb to be freed
- ***************************************************************************/
-
-void free_token_bucket(token_bucket *tb)
-{
-  free(tb);
-}
-
-
-/***************************************************************************
- *  duplicate_token_bucket - create a replica of a token bucket
- *
- *  input:
- *    tb - token bucket to be duplicated
- *
- *  return:
- *    replica of tb
- ***************************************************************************/
-
-token_bucket *duplicate_token_bucket(token_bucket *tb)
-{
-  token_bucket *tbnew = alloc_token_bucket();
-
-  init_token_bucket(tbnew, tb->type, tb->depth, tb->r, tb->R);
-
-  return tbnew;
-}
-
-
-
-
-/***************************************************************************
- *  pack_token_bucket - convert a token bucket data structure in packet format
- *
- *  input:
- *    p - address of the buffer where the token bucket is to be stored in 
- *        packet format (the buffer is pre-allocated)
- *    tb - token bucket to be converted in packet format
- *    
- *  output:
- *    length - length of the token bucket in packet format
- ***************************************************************************/
-
-void pack_token_bucket(char *p, token_bucket *tb, unsigned short *length)
-{
-  uint32_t temp;
-
-  p[0] = tb->type;
-  p += sizeof(char);
-  *length = sizeof(char);
-
-  temp = htons(tb->depth);
-  memcpy(p, &temp, sizeof(uint32_t));
-  p += sizeof(uint32_t);
-  *length += sizeof(uint32_t);
-
-  temp = htons(tb->r);
-  memcpy(p, &temp, sizeof(uint32_t));
-  p += sizeof(uint32_t);
-  *length += sizeof(uint32_t);
-
-  temp = htons(tb->R);
-  memcpy(p, &temp, sizeof(uint32_t));
-  p += sizeof(uint32_t);
-  *length += sizeof(uint32_t);
-}
-
-unsigned short get_token_bucket_len()
-{
-  return 3*sizeof(uint32_t) + sizeof(uint8_t);
-}
-
-
-/***************************************************************************
- *  unpack_token_bucket - copy token bucket info from packet to a tb 
- *                        data structure 
- *
- *  input:
- *    p - address where token bucket is stored in packet format
- *   
- *  return:
- *    token bucket data structure
- * 
- *  output:
- *    length - length of the token bucket info in packet format
- *
- ***************************************************************************/
-
-token_bucket *unpack_token_bucket(char *p, unsigned short *length)
-{
-  token_bucket *tb = alloc_token_bucket();
-
-  tb->type = *p;
-  *length = sizeof(char);
-  p += sizeof(char);
-
-  tb->depth = ntohs(*((uint32_t *)p));
-  *length += sizeof(uint32_t);
-  p += sizeof(uint32_t);
-
-  tb->r = ntohs(*((uint32_t *)p));
-  *length += sizeof(uint32_t);
-  p += sizeof(uint32_t);
-
-  tb->R = ntohs(*((uint32_t *)p));
-  *length += sizeof(uint32_t);
-  p += sizeof(uint32_t);
-
-  return tb;
-}
-
-
-/***************************************************************************
- *  check_token_bucket - check token bucket whether is well-formed
- *
- *  input:
- *    p - address where token bucket is stored in packet format
- *   
- *  return:
- *    error code; FALSE if no error
- * 
- *  output:
- *    length - length of the token bucket info in packet format
- *
- ***************************************************************************/
-
-int check_token_bucket(char *p, unsigned short *length)
-{
-  *length = 3*sizeof(uint32_t) + sizeof(uint8_t);
-  return FALSE;
-}
-
-
-/***************************************************************************
- *  token_bucket_accept_pkt - check whether token bucket constraints
- *                            allow to send packet
- *
- *  input:
- *    tb  - token bucket
- *    len - packet length
- *   
- *  return:
- *    1 - if the packet can be sent,
- *    0 - if the packet cannot be sent (in this case, the packet is dropped)
- * 
- *
- ***************************************************************************/
-
-int token_bucket_accept_pkt(token_bucket *tb, uint32_t len, uint64_t now)
-{
-  uint64_t tokens;
-
-  assert(tb);
-
-  /* update # of tokens in the bucket */
-  tokens = (now - tb->last_time)*tb->r/1000000ULL;
-  tb->tokens += tokens;
-
-  if (tb->tokens == 0) {
-    return 0;
-  }
-
-  if (tb->tokens <= tb->depth) {
-    tb->last_time += tokens*1000000ULL/tb->r;
-  } else {
-    tb->last_time = now;
-     /* number of tokens cannot exceed bucket's depth */ 
-    tb->tokens = tb->depth;
-  }
-
-  if (tb->type == TOKEN_BUCKET_BYTE) {
-    if (tb->tokens < len) {
-       /* not enough tokens; cannot send the packet */
-      return 0;
-    }
-    tb->tokens -= len;
-    return 1;
-  } else if (tb->type == TOKEN_BUCKET_PACKET) {
-    if (tb->tokens < 1) {
-      /* not enough tokens; cannot send the packet */
-      return 0;
-    }
-    tb->tokens--;
-    return 1;
-  } else
-    panic("token_bucket_accept_pkt: invalid token bucket type!\n");
-
-  /* we shouldn't get here, but we need to return something
-   * to make the compiler happy
-   */
-  return 0;
-}
- 
-
-/****************************************
- ** print token bucket; just for test  **
- ****************************************/
-
-void printf_token_bucket(token_bucket *tb, int indent)
-{
-  char buf[INDENT_BUF_LEN];
-
-  memset(buf, ' ', INDENT_BUF_LEN);
-  buf[indent] = 0;
-
-  printf("%s type=%d, depth=%u, r=%u, R=%u (tokens=%u, last_time=%llu)\n", 
-        buf, tb->type, tb->depth, tb->r, tb->R,
-        tb->tokens, (unsigned long long int)tb->last_time);
-}
-
+/***************************************************************************
+*                         token_bucket.c  -  description
+*                            -------------------
+*   begin                : Nov 20 2002
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
+
+#include "i3.h"
+#include "i3_fun.h"
+#include "i3_debug.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+/***************************************************************************
+*  alloc_token_bucket - allocate a token bucket data structure
+*
+*  return:
+*    pointer to the allocated token bucket
+***************************************************************************/
+
+token_bucket *alloc_token_bucket()
+{
+    token_bucket *tb;
+
+    tb = (token_bucket *) calloc(1, sizeof(token_bucket));
+    if (tb) {
+        return tb;
+    }
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,
+                    "alloc_token_bucket: memory allocation error.\n");
+    return NULL;
+}
+
+/***************************************************************************
+*  init_token_bucket - initialize token bucket's fields
+*
+*  return:
+*    pointer to the allocated token bucket
+***************************************************************************/
+
+void init_token_bucket(token_bucket *tb, uint8_t type,
+                       uint32_t depth, uint32_t r, uint32_t R)
+{
+    tb->type  = type;
+    tb->depth = depth;
+    tb->r     = r;
+    tb->R     = R;
+}
+
+/***************************************************************************
+*  free_token_bucket - free tb data structure
+*
+*  input:
+*    tb to be freed
+***************************************************************************/
+
+void free_token_bucket(token_bucket *tb)
+{
+    free(tb);
+}
+
+/***************************************************************************
+*  duplicate_token_bucket - create a replica of a token bucket
+*
+*  input:
+*    tb - token bucket to be duplicated
+*
+*  return:
+*    replica of tb
+***************************************************************************/
+
+token_bucket *duplicate_token_bucket(token_bucket *tb)
+{
+    token_bucket *tbnew = alloc_token_bucket();
+
+    init_token_bucket(tbnew, tb->type, tb->depth, tb->r, tb->R);
+
+    return tbnew;
+}
+
+/***************************************************************************
+*  pack_token_bucket - convert a token bucket data structure in packet format
+*
+*  input:
+*    p - address of the buffer where the token bucket is to be stored in
+*        packet format (the buffer is pre-allocated)
+*    tb - token bucket to be converted in packet format
+*
+*  output:
+*    length - length of the token bucket in packet format
+***************************************************************************/
+
+void pack_token_bucket(char *p, token_bucket *tb, unsigned short *length)
+{
+    uint32_t temp;
+
+    p[0]     = tb->type;
+    p       += sizeof(char);
+    *length  = sizeof(char);
+
+    temp     = htons(tb->depth);
+    memcpy(p, &temp, sizeof(uint32_t));
+    p       += sizeof(uint32_t);
+    *length += sizeof(uint32_t);
+
+    temp     = htons(tb->r);
+    memcpy(p, &temp, sizeof(uint32_t));
+    p       += sizeof(uint32_t);
+    *length += sizeof(uint32_t);
+
+    temp     = htons(tb->R);
+    memcpy(p, &temp, sizeof(uint32_t));
+    p       += sizeof(uint32_t);
+    *length += sizeof(uint32_t);
+}
+
+unsigned short get_token_bucket_len()
+{
+    return 3 * sizeof(uint32_t) + sizeof(uint8_t);
+}
+
+/***************************************************************************
+*  unpack_token_bucket - copy token bucket info from packet to a tb
+*                        data structure
+*
+*  input:
+*    p - address where token bucket is stored in packet format
+*
+*  return:
+*    token bucket data structure
+*
+*  output:
+*    length - length of the token bucket info in packet format
+*
+***************************************************************************/
+
+token_bucket *unpack_token_bucket(char *p, unsigned short *length)
+{
+    token_bucket *tb = alloc_token_bucket();
+
+    tb->type  = *p;
+    *length   = sizeof(char);
+    p        += sizeof(char);
+
+    tb->depth = ntohs(*((uint32_t *) p));
+    *length  += sizeof(uint32_t);
+    p        += sizeof(uint32_t);
+
+    tb->r     = ntohs(*((uint32_t *) p));
+    *length  += sizeof(uint32_t);
+    p        += sizeof(uint32_t);
+
+    tb->R     = ntohs(*((uint32_t *) p));
+    *length  += sizeof(uint32_t);
+    p        += sizeof(uint32_t);
+
+    return tb;
+}
+
+/***************************************************************************
+*  check_token_bucket - check token bucket whether is well-formed
+*
+*  input:
+*    p - address where token bucket is stored in packet format
+*
+*  return:
+*    error code; FALSE if no error
+*
+*  output:
+*    length - length of the token bucket info in packet format
+*
+***************************************************************************/
+
+int check_token_bucket(char *p, unsigned short *length)
+{
+    *length = 3 * sizeof(uint32_t) + sizeof(uint8_t);
+    return FALSE;
+}
+
+/***************************************************************************
+*  token_bucket_accept_pkt - check whether token bucket constraints
+*                            allow to send packet
+*
+*  input:
+*    tb  - token bucket
+*    len - packet length
+*
+*  return:
+*    1 - if the packet can be sent,
+*    0 - if the packet cannot be sent (in this case, the packet is dropped)
+*
+*
+***************************************************************************/
+
+int token_bucket_accept_pkt(token_bucket *tb, uint32_t len, uint64_t now)
+{
+    uint64_t tokens;
+
+    assert(tb);
+
+    /* update # of tokens in the bucket */
+    tokens      = (now - tb->last_time) * tb->r / 1000000ULL;
+    tb->tokens += tokens;
+
+    if (tb->tokens == 0) {
+        return 0;
+    }
+
+    if (tb->tokens <= tb->depth) {
+        tb->last_time += tokens * 1000000ULL / tb->r;
+    } else {
+        tb->last_time = now;
+        /* number of tokens cannot exceed bucket's depth */
+        tb->tokens    = tb->depth;
+    }
+
+    if (tb->type == TOKEN_BUCKET_BYTE) {
+        if (tb->tokens < len) {
+            /* not enough tokens; cannot send the packet */
+            return 0;
+        }
+        tb->tokens -= len;
+        return 1;
+    } else if (tb->type == TOKEN_BUCKET_PACKET) {
+        if (tb->tokens < 1) {
+            /* not enough tokens; cannot send the packet */
+            return 0;
+        }
+        tb->tokens--;
+        return 1;
+    } else {
+        panic("token_bucket_accept_pkt: invalid token bucket type!\n");
+    }
+
+    /* we shouldn't get here, but we need to return something
+     * to make the compiler happy
+     */
+    return 0;
+}
+
+/****************************************
+** print token bucket; just for test  **
+****************************************/
+
+void printf_token_bucket(token_bucket *tb, int indent)
+{
+    char buf[INDENT_BUF_LEN];
+
+    memset(buf, ' ', INDENT_BUF_LEN);
+    buf[indent] = 0;
+
+    printf("%s type=%d, depth=%u, r=%u, R=%u (tokens=%u, last_time=%llu)\n",
+           buf, tb->type, tb->depth, tb->r, tb->R,
+           tb->tokens, (unsigned long long int) tb->last_time);
+}

=== modified file 'i3/i3/token_bucket.h'
--- i3/i3/token_bucket.h        2010-01-06 22:17:32 +0000
+++ i3/i3/token_bucket.h        2010-02-11 11:49:47 +0000
@@ -1,25 +1,25 @@
-/***************************************************************************
-                          token_bucket.h  -  description
-                             -------------------
-    begin                : Fre Jun 20 2003
-    copyright            : (C) 2003 by klaus
-    email                : wehrle@xxxxxxxxxxxxxxxxx
- ***************************************************************************/
-
-#ifndef TOKEN_BUCKET_H
-#define TOKEN_BUCKET_H
- 
-/* functions implemented in token_bucket.c */
-token_bucket *alloc_token_bucket(void);
-void free_token_bucket(token_bucket *tb);
-void init_token_bucket(token_bucket *tb, uint8_t type,
-                      uint32_t depth, uint32_t r, uint32_t R);
-token_bucket *duplicate_token_bucket(token_bucket *tb);
-void pack_token_bucket(char *p, token_bucket *tb, unsigned short *length);
-unsigned short get_token_bucket_len(void);
-token_bucket *unpack_token_bucket(char *p, unsigned short *length);
-int check_token_bucket(char *p, unsigned short *length);
-int token_bucket_accept_pkt(token_bucket *tb, uint32_t len, uint64_t now);
-void printf_token_bucket(token_bucket *tb, int indent);
-
-#endif // TOKEN_BUCKET_H 
+/***************************************************************************
+*                         token_bucket.h  -  description
+*                            -------------------
+*   begin                : Fre Jun 20 2003
+*   copyright            : (C) 2003 by klaus
+*   email                : wehrle@xxxxxxxxxxxxxxxxx
+***************************************************************************/
+
+#ifndef TOKEN_BUCKET_H
+#define TOKEN_BUCKET_H
+
+/* functions implemented in token_bucket.c */
+token_bucket *alloc_token_bucket(void);
+void free_token_bucket(token_bucket *tb);
+void init_token_bucket(token_bucket *tb, uint8_t type,
+                       uint32_t depth, uint32_t r, uint32_t R);
+token_bucket *duplicate_token_bucket(token_bucket *tb);
+void pack_token_bucket(char *p, token_bucket *tb, unsigned short *length);
+unsigned short get_token_bucket_len(void);
+token_bucket *unpack_token_bucket(char *p, unsigned short *length);
+int check_token_bucket(char *p, unsigned short *length);
+int token_bucket_accept_pkt(token_bucket *tb, uint32_t len, uint64_t now);
+void printf_token_bucket(token_bucket *tb, int indent);
+
+#endif // TOKEN_BUCKET_H

=== modified file 'i3/i3_client/coordinates.c'
--- i3/i3_client/coordinates.c  2009-12-11 22:49:11 +0000
+++ i3/i3_client/coordinates.c  2010-02-11 11:49:47 +0000
@@ -16,20 +16,20 @@
 float objective_function(float dim[], int ndim)
 {
     int i;
-    float sum = 0;
+    float sum        = 0;
     float l1, l2, temp;
-    
+
     static int count = 0;
     ++count;
-    
+
     // TODO: handle wraparound for longitude
     assert(curr_num > 0);
     for (i = 0; i < curr_num; i++) {
-       l1 = dim[0]-curr_coord_rtt[i].coord.latitude;
-       l2 = dim[1]-curr_coord_rtt[i].coord.longitude;
+        l1   = dim[0] - curr_coord_rtt[i].coord.latitude;
+        l2   = dim[1] - curr_coord_rtt[i].coord.longitude;
 
-       temp = (float)(sqrt(l1*l1 + l2*l2) - 
dim[2]*((float)curr_coord_rtt[i].rtt/1000.0));
-       sum += temp*temp;
+        temp = (float) (sqrt(l1 * l1 + l2 * l2) - dim[2] * ((float) 
curr_coord_rtt[i].rtt / 1000.0));
+        sum += temp * temp;
     }
 
     return sum;
@@ -42,51 +42,53 @@
     static int firsttime = 1;
     static float **p;
     static float *y;
-    int mean[] = {0, 0, 0, 10};
-    int width[] = {0, 180, 360, 20};
- 
+    int mean[]           = {0, 0, 0, 10};
+    int width[]          = {0, 180, 360, 20};
+
     if (firsttime) {
-       p = (float **)malloc(sizeof(float *)*(DIM+2));
-       y = (float *)malloc(sizeof(float)*(DIM+2));
-       for (i = 1; i <= DIM+1; ++i) {
-           p[i] = (float *)malloc(sizeof(float)*(DIM+1));
-       }
-       firsttime = 0;
+        p         = (float **) malloc(sizeof(float *) * (DIM + 2));
+        y         = (float *) malloc(sizeof(float) * (DIM + 2));
+        for (i = 1; i <= DIM + 1; ++i) {
+            p[i] = (float *) malloc(sizeof(float) * (DIM + 1));
+        }
+        firsttime = 0;
     }
-    
-    curr_num = num;
+
+    curr_num       = num;
     curr_coord_rtt = coord_rtt;
 
     if (curr_num == 0) {
-       printf("No landmarks specified for coordinate computation.  Exiting 
function...\n");
-       return;
+        printf("No landmarks specified for coordinate computation.  Exiting 
function...\n");
+        return;
     }
-   
+
     /* choose random numbers, and initializations */
-    for (i = 1; i <= DIM+1; ++i) {
-       for (j = 1; j <= DIM; j++) {
-           p[i][j] = (float)(mean[j] + rand() % width[j] - width[j]/2);
-       }
-    }
-    for (i = 1; i <= DIM+1; ++i) {
-       y[i] = objective_function(p[i], DIM);
-    }
-   
+    for (i = 1; i <= DIM + 1; ++i) {
+        for (j = 1; j <= DIM; j++) {
+            p[i][j] = (float) (mean[j] + rand() % width[j] - width[j] / 2);
+        }
+    }
+    for (i = 1; i <= DIM + 1; ++i) {
+        y[i] = objective_function(p[i], DIM);
+    }
+
     /* multiple runs */
 #define NUM_RUNS_DOWNHILL 10
-    for (i = 0; i < NUM_RUNS_DOWNHILL; i++) 
-       downhill_simplex(p, y, DIM, FTOL, objective_function, &nfunc);
-    
+    for (i = 0; i < NUM_RUNS_DOWNHILL; i++) {
+        downhill_simplex(p, y, DIM, FTOL, objective_function, &nfunc);
+    }
+
     printf("%.2f %.2f %.2f\n", p[1][1], p[1][2], p[1][3]);
-    my_coordinates.latitude = p[1][1];
+    my_coordinates.latitude  = p[1][1];
     my_coordinates.longitude = p[1][2];
 }
 
 float coordinates_distance(Coordinates coord)
 {
-    if (COORD_UNDEFINED == coord.latitude || COORD_UNDEFINED == 
coord.longitude)
-       return -1;
-    
-    return (float)(sqrt(pow(coord.latitude - my_coordinates.latitude, 2) + 
-           pow(coord.longitude - my_coordinates.longitude, 2)));
+    if (COORD_UNDEFINED == coord.latitude || COORD_UNDEFINED == 
coord.longitude) {
+        return -1;
+    }
+
+    return (float) (sqrt(pow(coord.latitude - my_coordinates.latitude, 2) +
+                         pow(coord.longitude - my_coordinates.longitude, 2)));
 }

=== modified file 'i3/i3_client/coordinates.h'
--- i3/i3_client/coordinates.h  2009-12-11 22:49:11 +0000
+++ i3/i3_client/coordinates.h  2010-02-11 11:49:47 +0000
@@ -16,7 +16,7 @@
 
 typedef struct Coordinates_RTT {
     Coordinates coord;
-    uint64_t rtt;
+    uint64_t    rtt;
 } Coordinates_RTT;
 
 void compute_coordinates(int num, Coordinates_RTT coord_rtt[]);

=== modified file 'i3/i3_client/downhill_simplex.c'
--- i3/i3_client/downhill_simplex.c     2009-12-11 22:49:11 +0000
+++ i3/i3_client/downhill_simplex.c     2010-02-11 11:49:47 +0000
@@ -1,12 +1,12 @@
 /*
  * This software is a copyright (c) of Carnegie Mellon University, 2002.
- *           
+ *
  * Permission to reproduce, use and prepare derivative works of this
  * software for use is granted provided the copyright and "No Warranty"
  * statements are included with all reproductions and derivative works.
  * This software may also be redistributed provided that the copyright
  * and "No Warranty" statements are included in all redistributions.
- *           
+ *
  * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.  CARNEGIE
  * MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR
  * IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF
@@ -29,167 +29,164 @@
 #define NMAX 500000
 
 /*
-  note: all effective array indices are 1..N, not 0..N-1
-
-  simplex - the initial simplex, must contain d + 1 points
-  values - the initial function values at the simplex points
-  d - the number of dimensions
-  ftol - the tolerate for convergence
-  obj - the objective function to minimize
-  num_eval - the number of evaluations of obj
-  stuff - things that are needed by obj
-*/
+ * note: all effective array indices are 1..N, not 0..N-1
+ *
+ * simplex - the initial simplex, must contain d + 1 points
+ * values - the initial function values at the simplex points
+ * d - the number of dimensions
+ * ftol - the tolerate for convergence
+ * obj - the objective function to minimize
+ * num_eval - the number of evaluations of obj
+ * stuff - things that are needed by obj
+ */
 void downhill_simplex(float **simplex, float *values, int d, float ftol,
-                     float (*obj)(float *, int), int *num_eval) {
-
-  int i, j, low, high, second_high, ssize;
-  float rtol, sum, *simplex_sum, *test_point, test_value, mult;
-
-  /* initializations */
-  *num_eval = 0;
-  ssize = d + 1; /* size of the simplex */
-
-  /* for each dimension, pre-compute the sum of all points */
-  /* this is used later to compute the average coordinates */
-  simplex_sum = (float*) malloc(sizeof(float)*(d+1)); /* array starts at 1 */
-  for (i=1; i<=d; i++) { 
-    sum = 0.0;
-    for(j=1; j<=ssize; j++) {
-      sum = sum + simplex[j][i];
-    }
-    simplex_sum[i] = sum;
-  }
-
-  /* create a test point */
-  test_point = (float*) malloc(sizeof(float)*(d+1)); /* array starts at 1 */
-
-
-  /* begin algorithm */
-  while (1) {
-
-    /* find the lowest point, the highest point and the second highest
-       point in the simplex */
-    if (values[1] > values[2]) {
-      low = 2;
-      high = 1;
-      second_high = 2;
-    } else {
-      low = 1;
-      high = 2;
-      second_high = 1;
-    }
-    for (i=1; i<=ssize; i++) {
-      if (values[i] > values[high]) {
-       second_high = high;
-       high = i;
-      } else if (values[i] > values[second_high] && i != high) {
-       second_high = i;
-      } else if (values[i] <= values[low]) {
-       low = i;
-      }
-    }
-
-
-    /* we will quit if there are too many tries
-       the tolerance is met, or if the function
-       value is so low that we really don't care anymore
-    */
-    rtol=2.0*fabs(values[high]-values[low])/
-      (fabs(values[high])+fabs(values[low])+TINY);
-    if (*num_eval >= NMAX || rtol < ftol || values[low] < 1.0e-6) {
-      values[1] = values[low];
-      for (i=1; i<=d; i++) {
-       simplex[1][i] = simplex[low][i];
-      }
-      break;
-    }
-
-
-    /* first try to reflect the high point across the mean point */
-    /* i.e. want (x_mean - x_high) = - (x_mean - x_test) */
-    mult = 2.0/d;
-    for (i=1; i<=d; i++) {
-      test_point[i] = (simplex_sum[i] - simplex[high][i])*mult
-       - simplex[high][i];
-    }
-    test_value = (*obj)(&test_point[1], d);
-    (*num_eval)++;
-    if (test_value < values[high]) {
-      /* better point, update the simplex, update also the sum */
-      values[high] = test_value;
-      for (i=1; i<=d; i++) {
-       simplex_sum[i] = simplex_sum[i] - simplex[high][i] + test_point[i];
-       simplex[high][i] = test_point[i];
-      }
-    }
-
-    if (test_value <= values[low]) {
-      /* the new point is even better than our lowest point, okay, now,
-        extend the point we just found even further
-        i.e. want 2*(x_mean - x_high) = (x_mean - x_test)
-      */
-      mult = -1.0/d;
-      for (i=1; i<=d; i++) {
-       test_point[i] = (simplex_sum[i] - simplex[high][i])*mult
-         + 2.0*simplex[high][i];
-      }
-      test_value = (*obj)(&test_point[1], d);
-      (*num_eval)++;
-      if (test_value < values[high]) {
-       /* better point, update the simplex, update also the sum */
-       values[high] = test_value;
-       for (i=1; i<=d; i++) {
-         simplex_sum[i] = simplex_sum[i] - simplex[high][i] + test_point[i];
-         simplex[high][i] = test_point[i];
-       }
-      }
-
-    } else if (test_value >= values[second_high]) {
-      /* the new point is still the highest, no improvement,
-         so we are going to shrink the high point towards the mean
-        i.e. want (x_mean - x_high) = 2*(x_mean - x_test)
-      */
-      mult = 0.5/d;
-      for (i=1; i<=d; i++) {
-       test_point[i] = (simplex_sum[i] - simplex[high][i])*mult
-         + 0.5*simplex[high][i];
-      }
-      test_value = (*obj)(&test_point[1], d);
-      (*num_eval)++;
-      if (test_value < values[high]) {
-       /* better point, update the simplex, update also the sum */
-       values[high] = test_value;
-       for (i=1; i<=d; i++) {
-         simplex_sum[i] = simplex_sum[i] - simplex[high][i] + test_point[i];
-         simplex[high][i] = test_point[i];
-       }
-      } else {
-       /* no good, we better just contract the whole simplex
-          toward the low point
-       */
-       for (i=1; i<=ssize; i++) {
-         if (i != low) {
-           for (j=1; j<=d; j++) {
-             simplex[i][j]=test_point[j]=0.5*(simplex[i][j]+simplex[low][j]);
-           }
-           values[i]=(*obj)(&test_point[1], d);
-         }
-       }
-       *num_eval = *num_eval + d;
-
-       /* recompute the sums */
-       for (i=1; i<=d; i++) { 
-         sum = 0.0;
-         for(j=1; j<=ssize; j++) {
-           sum = sum + simplex[j][i];
-         }
-         simplex_sum[i] = sum;
-       }
-      }
-    }
-  }
-
-  free(simplex_sum);
-  free(test_point);
-
+                      float (*obj)(float *, int), int *num_eval)
+{
+    int i, j, low, high, second_high, ssize;
+    float rtol, sum, *simplex_sum, *test_point, test_value, mult;
+
+    /* initializations */
+    *num_eval   = 0;
+    ssize       = d + 1; /* size of the simplex */
+
+    /* for each dimension, pre-compute the sum of all points */
+    /* this is used later to compute the average coordinates */
+    simplex_sum = (float *) malloc(sizeof(float) * (d + 1)); /* array starts 
at 1 */
+    for (i = 1; i <= d; i++) {
+        sum            = 0.0;
+        for (j = 1; j <= ssize; j++) {
+            sum = sum + simplex[j][i];
+        }
+        simplex_sum[i] = sum;
+    }
+
+    /* create a test point */
+    test_point = (float *) malloc(sizeof(float) * (d + 1)); /* array starts at 
1 */
+
+
+    /* begin algorithm */
+    while (1) {
+        /* find the lowest point, the highest point and the second highest
+         * point in the simplex */
+        if (values[1] > values[2]) {
+            low         = 2;
+            high        = 1;
+            second_high = 2;
+        } else {
+            low         = 1;
+            high        = 2;
+            second_high = 1;
+        }
+        for (i = 1; i <= ssize; i++) {
+            if (values[i] > values[high]) {
+                second_high = high;
+                high        = i;
+            } else if (values[i] > values[second_high] && i != high) {
+                second_high = i;
+            } else if (values[i] <= values[low]) {
+                low = i;
+            }
+        }
+
+
+        /* we will quit if there are too many tries
+         * the tolerance is met, or if the function
+         * value is so low that we really don't care anymore
+         */
+        rtol = 2.0 * fabs(values[high] - values[low]) /
+               (fabs(values[high]) + fabs(values[low]) + TINY);
+        if (*num_eval >= NMAX || rtol < ftol || values[low] < 1.0e-6) {
+            values[1] = values[low];
+            for (i = 1; i <= d; i++) {
+                simplex[1][i] = simplex[low][i];
+            }
+            break;
+        }
+
+
+        /* first try to reflect the high point across the mean point */
+        /* i.e. want (x_mean - x_high) = - (x_mean - x_test) */
+        mult = 2.0 / d;
+        for (i = 1; i <= d; i++) {
+            test_point[i] = (simplex_sum[i] - simplex[high][i]) * mult
+                            - simplex[high][i];
+        }
+        test_value = (*obj)(&test_point[1], d);
+        (*num_eval)++;
+        if (test_value < values[high]) {
+            /* better point, update the simplex, update also the sum */
+            values[high] = test_value;
+            for (i = 1; i <= d; i++) {
+                simplex_sum[i]   = simplex_sum[i] - simplex[high][i] + 
test_point[i];
+                simplex[high][i] = test_point[i];
+            }
+        }
+
+        if (test_value <= values[low]) {
+            /* the new point is even better than our lowest point, okay, now,
+             * extend the point we just found even further
+             * i.e. want 2*(x_mean - x_high) = (x_mean - x_test)
+             */
+            mult = -1.0 / d;
+            for (i = 1; i <= d; i++) {
+                test_point[i] = (simplex_sum[i] - simplex[high][i]) * mult
+                                + 2.0 * simplex[high][i];
+            }
+            test_value = (*obj)(&test_point[1], d);
+            (*num_eval)++;
+            if (test_value < values[high]) {
+                /* better point, update the simplex, update also the sum */
+                values[high] = test_value;
+                for (i = 1; i <= d; i++) {
+                    simplex_sum[i]   = simplex_sum[i] - simplex[high][i] + 
test_point[i];
+                    simplex[high][i] = test_point[i];
+                }
+            }
+        } else if (test_value >= values[second_high]) {
+            /* the new point is still the highest, no improvement,
+             * so we are going to shrink the high point towards the mean
+             * i.e. want (x_mean - x_high) = 2*(x_mean - x_test)
+             */
+            mult = 0.5 / d;
+            for (i = 1; i <= d; i++) {
+                test_point[i] = (simplex_sum[i] - simplex[high][i]) * mult
+                                + 0.5 * simplex[high][i];
+            }
+            test_value = (*obj)(&test_point[1], d);
+            (*num_eval)++;
+            if (test_value < values[high]) {
+                /* better point, update the simplex, update also the sum */
+                values[high] = test_value;
+                for (i = 1; i <= d; i++) {
+                    simplex_sum[i]   = simplex_sum[i] - simplex[high][i] + 
test_point[i];
+                    simplex[high][i] = test_point[i];
+                }
+            } else {
+                /* no good, we better just contract the whole simplex
+                 * toward the low point
+                 */
+                for (i = 1; i <= ssize; i++) {
+                    if (i != low) {
+                        for (j = 1; j <= d; j++) {
+                            simplex[i][j] = test_point[j] = 0.5 * 
(simplex[i][j] + simplex[low][j]);
+                        }
+                        values[i] = (*obj)(&test_point[1], d);
+                    }
+                }
+                *num_eval = *num_eval + d;
+
+                /* recompute the sums */
+                for (i = 1; i <= d; i++) {
+                    sum            = 0.0;
+                    for (j = 1; j <= ssize; j++) {
+                        sum = sum + simplex[j][i];
+                    }
+                    simplex_sum[i] = sum;
+                }
+            }
+        }
+    }
+
+    free(simplex_sum);
+    free(test_point);
 }

=== modified file 'i3/i3_client/downhill_simplex.h'
--- i3/i3_client/downhill_simplex.h     2009-12-11 22:49:11 +0000
+++ i3/i3_client/downhill_simplex.h     2010-02-11 11:49:47 +0000
@@ -2,6 +2,6 @@
 #define __DOWNHILL_SIMPLEX_H
 
 void downhill_simplex(float **simplex, float *values, int dim, float ftol,
-       float (*obj_func)(float [], int ndim), int *num_eval);
-    
+                      float (*obj_func)(float [], int ndim), int *num_eval);
+
 #endif

=== modified file 'i3/i3_client/http.c'
--- i3/i3_client/http.c 2009-12-29 21:08:52 +0000
+++ i3/i3_client/http.c 2010-02-11 11:49:47 +0000
@@ -1,7 +1,7 @@
 /* webclient.c written by detour@xxxxxxxxxxxxxx
  *
  * This code will connect to a host and attempt to download
- * the source for an http page.  
+ * the source for an http page.
  *
  * run: ./webclient <host>
  *
@@ -15,7 +15,7 @@
 #include <string.h>
 #include <errno.h>
 #ifndef _WIN32
-       #include <unistd.h>
+        #include <unistd.h>
 #endif
 #include "../utils/netwrap.h"
 
@@ -30,7 +30,7 @@
 #define STR_ID_LEN   41  /* two chars per real "byte" plus one for end of 
string */
 #define PORT_LEN 10 /* just enough to store a port in ascii */
 #define IP_LEN   65  /* just in case, for IPv6 */
-#define BUF_SIZE 65535 
+#define BUF_SIZE 65535
 #define CHAR_LEN 4
 
 #ifndef TRUE
@@ -39,261 +39,275 @@
 #endif
 
 
-/* get host name and format get command from input 
+/* get host name and format get command from input
  * example,
  *   input: www.cs.berkeley.edu/~istoica/index.html
  *   host:  www.cs.berkeley.edu
  *   get_cmd: GET /~istoica/index.html HTTP/1.0 */
-void get_args(char *input, char *host, char *get_cmd, 
-               int *port, int buf_len) 
+void get_args(char *input, char *host, char *get_cmd,
+              int *port, int buf_len)
 {
-  char *p1, *p2, *end, *ptemp;
-
-  if (strlen(input) >= buf_len) {
-    fprintf(stderr, "input string too large: %s\n", input);
-    return;
-  }
-      
-  /* get host name */
-  ptemp = get_cmd;
-  strcpy(ptemp, "GET ");
-  ptemp += strlen("GET ");
-
-  end = input + strlen(input);
-  p1 = strstr(input, "/");
-  p2 = strstr(input, ":");
-
-  if (NULL == p1) p1 = end;
-  if (NULL == p2) p2 = p1;
-
-  if (p1 != end) {
-      strcpy(ptemp, p1);
-      ptemp += strlen(p1);
-  } else {
-      strcpy(ptemp, "/ ");
-      ptemp += strlen("/ ");
-  }
-  
-  if (p2 != p1) {
-      memcpy(host, p2+1, p1-p2-1);
-      host[p1-p2-1] = 0;
-      *port = atoi(host);
-  } else {
-      *port = 0;
-  }
-  
-  memcpy(host, input, p2-input);
-  host[p2-input] = 0;
-  
-  strcpy(ptemp, " HTTP/1.0\n\n");
-}   
-
-/* get an entry containing the host IP address, port number, and 20 byte ID */ 
+    char *p1, *p2, *end, *ptemp;
+
+    if (strlen(input) >= buf_len) {
+        fprintf(stderr, "input string too large: %s\n", input);
+        return;
+    }
+
+    /* get host name */
+    ptemp  = get_cmd;
+    strcpy(ptemp, "GET ");
+    ptemp += strlen("GET ");
+
+    end    = input + strlen(input);
+    p1     = strstr(input, "/");
+    p2     = strstr(input, ":");
+
+    if (NULL == p1) {
+        p1 = end;
+    }
+    if (NULL == p2) {
+        p2 = p1;
+    }
+
+    if (p1 != end) {
+        strcpy(ptemp, p1);
+        ptemp += strlen(p1);
+    } else {
+        strcpy(ptemp, "/ ");
+        ptemp += strlen("/ ");
+    }
+
+    if (p2 != p1) {
+        memcpy(host, p2 + 1, p1 - p2 - 1);
+        host[p1 - p2 - 1] = 0;
+        *port             = atoi(host);
+    } else {
+        *port = 0;
+    }
+
+    memcpy(host, input, p2 - input);
+    host[p2 - input] = 0;
+
+    strcpy(ptemp, " HTTP/1.0\n\n");
+}
+
+/* get an entry containing the host IP address, port number, and 20 byte ID */
 int get_entry(char *buf, char *end, char *ip_addr, int *port,
-               char *id, char *status, float *latitude, float *longitude)
+              char *id, char *status, float *latitude, float *longitude)
 {
-  char *ip_start, *port_start, *id_start, *status_start, *coord_start, *temp, 
*p1, *p2;
-  char num_str[PORT_LEN];
-  int len_id;
-  *status = FALSE;
-  
-  /* split fields */
-  ip_start = strstr(buf, " ");
-  if (ip_start == NULL || ip_start > end)
-    return 0;
-  else
-    ip_start++;
-  id_start = strstr(ip_start, " ");
-  if (id_start == NULL || id_start > end)
-    return 0;
-  else
-    id_start++;
-  status_start = strstr(id_start, " ");
-  if (status_start == NULL || status_start > end)
-    return 0;
-  else
-    status_start++;
-  coord_start = strstr(status_start, " ");
-  if (coord_start == NULL || coord_start > end)
-      return 0;
-  else
-      coord_start++;
-
-  /* lat_start = strstr(status_start, " ");
-  if (lat_start == NULL || lat_start > end)
-      return 0;
-  else
-      lat_start++;
-  long_start = strstr(lat_start, " ");
-  if (long_start == NULL || long_start > end)
-      return 0;
-  else
-      long_start++;*/
- 
-  /* look for delimiter between ip address and port number ":" ... */
-  port_start = strstr(ip_start, ":");
-  if (port_start == NULL || port_start >= id_start)
-    return 0;
-  else
-    port_start++;
-
-  /* ... make sure that at the left of ":" there is an IP address */ 
-  for (temp = port_start-1; *temp != '.'; temp--) {
-    if (port_start-1 - temp > CHAR_LEN) {
-      /* not an IP address return */
-      return 0;
-    }
-  }
-    
-  /* get address */
-  if (port_start-1 - ip_start > IP_LEN)
-    return 0;
-  memcpy(ip_addr, ip_start, port_start-1 - ip_start);
-  ip_addr[port_start-1 - ip_start] = 0;
-  
-  /* get port */
-  if (id_start-1 - port_start > PORT_LEN)
-    return 0;
-  memcpy(num_str, port_start, id_start-1 - port_start);
-  num_str[id_start-1 - port_start] = 0;
-  *port = atoi(num_str);
-
-  /* get id */
-  if (status_start-1 - id_start > STR_ID_LEN)
-    len_id = STR_ID_LEN;
-  else
-    len_id = status_start-1 - id_start;
-  memcpy(id, id_start, len_id);
-  id[len_id] = 0;
-
-  /* get coordinates: TODO checks */
-  sscanf(coord_start, "%f %f", latitude, longitude);
-  
-  /* get status */
-  if ((p1 = strstr(status_start, "No")) > end)
-    p1 = NULL;
-  if ((p2 = strstr(status_start, "Running")) > end)
-    p2 = NULL;
-
-  if (p1 && p2)
-    return 0;
-  else if (p2) {
-    *status = TRUE;
-    return 1;
-  }
-  else if (p1)
-    return 1;
-    
-  return 0;
+    char *ip_start, *port_start, *id_start, *status_start, *coord_start, 
*temp, *p1, *p2;
+    char num_str[PORT_LEN];
+    int len_id;
+    *status      = FALSE;
+
+    /* split fields */
+    ip_start     = strstr(buf, " ");
+    if (ip_start == NULL || ip_start > end) {
+        return 0;
+    } else {
+        ip_start++;
+    }
+    id_start     = strstr(ip_start, " ");
+    if (id_start == NULL || id_start > end) {
+        return 0;
+    } else {
+        id_start++;
+    }
+    status_start = strstr(id_start, " ");
+    if (status_start == NULL || status_start > end) {
+        return 0;
+    } else {
+        status_start++;
+    }
+    coord_start  = strstr(status_start, " ");
+    if (coord_start == NULL || coord_start > end) {
+        return 0;
+    } else {
+        coord_start++;
+    }
+
+    /* lat_start = strstr(status_start, " ");
+     * if (lat_start == NULL || lat_start > end)
+     *  return 0;
+     * else
+     *  lat_start++;
+     * long_start = strstr(lat_start, " ");
+     * if (long_start == NULL || long_start > end)
+     *  return 0;
+     * else
+     *  long_start++;*/
+
+    /* look for delimiter between ip address and port number ":" ... */
+    port_start = strstr(ip_start, ":");
+    if (port_start == NULL || port_start >= id_start) {
+        return 0;
+    } else {
+        port_start++;
+    }
+
+    /* ... make sure that at the left of ":" there is an IP address */
+    for (temp = port_start - 1; *temp != '.'; temp--) {
+        if (port_start - 1 - temp > CHAR_LEN) {
+            /* not an IP address return */
+            return 0;
+        }
+    }
+
+    /* get address */
+    if (port_start - 1 - ip_start > IP_LEN) {
+        return 0;
+    }
+    memcpy(ip_addr, ip_start, port_start - 1 - ip_start);
+    ip_addr[port_start - 1 - ip_start] = 0;
+
+    /* get port */
+    if (id_start - 1 - port_start > PORT_LEN) {
+        return 0;
+    }
+    memcpy(num_str, port_start, id_start - 1 - port_start);
+    num_str[id_start - 1 - port_start] = 0;
+    *port                              = atoi(num_str);
+
+    /* get id */
+    if (status_start - 1 - id_start > STR_ID_LEN) {
+        len_id = STR_ID_LEN;
+    } else {
+        len_id = status_start - 1 - id_start;
+    }
+    memcpy(id, id_start, len_id);
+    id[len_id] = 0;
+
+    /* get coordinates: TODO checks */
+    sscanf(coord_start, "%f %f", latitude, longitude);
+
+    /* get status */
+    if ((p1 = strstr(status_start, "No")) > end) {
+        p1 = NULL;
+    }
+    if ((p2 = strstr(status_start, "Running")) > end) {
+        p2 = NULL;
+    }
+
+    if (p1 && p2) {
+        return 0;
+    } else if (p2) {
+        *status = TRUE;
+        return 1;
+    } else if (p1)   {
+        return 1;
+    }
+
+    return 0;
 }
 
 int get_address(char *web_url, I3ServerList *list)
 {
-  nw_skt_t sockid;
-  int bufsize;
-  char host[STR_LEN];
-  char get_cmd[STR_LEN];
-  char buffer[BUF_SIZE];
-  char ip_addr[IP_LEN];
-  char id[STR_ID_LEN];
-  char status;
-  int  port;
-  Coordinates coord;
-  struct sockaddr_in socketaddr;
-  struct hostent *hostaddr;
-  struct servent *servaddr;
-  struct protoent *protocol;
-  char *p, *next;
-  int offset = 0;
-
-  /* get host name and format the get command */
-  get_args(web_url, host, get_cmd, &port, STR_LEN);
-
-  /* Resolve the host name */
-  if (!(hostaddr = gethostbyname(host))) {
-    fprintf(stderr, "Getting server list: error resolving host %s.", host);
-    return -1;
-  }
-
-  /* clear and initialize socketaddr */
-  memset(&socketaddr, 0, sizeof(socketaddr));
-  socketaddr.sin_family = AF_INET;
-
-  /* setup the servent struct using getservbyname */
-  servaddr = getservbyname(SERVICE, PROTOCOL);
-  if (0 == port)
-      socketaddr.sin_port = servaddr->s_port;
-  else
-      socketaddr.sin_port = htons(port);
-
-  memcpy(&socketaddr.sin_addr, hostaddr->h_addr, hostaddr->h_length);
-
-  /* protocol must be a number when used with socket()
-     since we are using tcp protocol->p_proto will be 0 */
-  protocol = getprotobyname(PROTOCOL);
-
-  sockid = socket(AF_INET, SOCK_STREAM, protocol->p_proto);
-  if (sockid < 0) {
-    fprintf(stderr, "get: error creating socket\n");
-    return -1;
-  }
-
-  /* everything is setup, now we connect */
-  if(connect(sockid, (struct sockaddr *)&socketaddr, sizeof(socketaddr)) == 
-1) {
-    fprintf(stderr, "get: error connecting\n");
-    nw_close(sockid);
-    return -1;
-  }
-
-  /* send our get request for http */
-  if (send(sockid, get_cmd, strlen(get_cmd), 0) == -1) {
-    fprintf(stderr, "get: error sending data\n");
-    nw_close(sockid);
-    return -1;
-  }
-
-  //printf ("8888:   start get\n");
-  /* read the socket until its clear then exit */
-  while ( (bufsize = recv(sockid, buffer+offset, sizeof(buffer)-offset-1, 0))) 
{
-
-    if (bufsize == -1) {
-        I3_PRINT_DEBUG1 (I3_DEBUG_LEVEL_MINIMAL,
-                "Error while getting list of i3 servers in get_addr: %s.\n",
-                strerror (errno)
-            );
-        break;
-    }
-
-    buffer[offset+bufsize] = 0;
-    p = buffer;
-
-    while ((next = strstr(p, "\n")) != NULL) {
-      if (get_entry(p, next, ip_addr, &port, id, &status, 
-                 &(coord.latitude), &(coord.longitude))) {
-       if (status) {
-           I3_PRINT_DEBUG5(I3_DEBUG_LEVEL_VERBOSE, "GET: %s %d %s %.1f %.1f\n",
-                   ip_addr, port, id, coord.latitude, coord.longitude);
-           update_i3server(list, ntohl(inet_addr(ip_addr)), 
-                           port, atoi3id(id), coord);
-       }
-      }
-      p = next + 1;
-    }
-
-    memmove(buffer, p, strlen(p));
-    offset = strlen(p);
-  }
-  //printf ("8888:   stop get\n");
-  nw_close(sockid);
-  return 0;
+    nw_skt_t sockid;
+    int bufsize;
+    char host[STR_LEN];
+    char get_cmd[STR_LEN];
+    char buffer[BUF_SIZE];
+    char ip_addr[IP_LEN];
+    char id[STR_ID_LEN];
+    char status;
+    int port;
+    Coordinates coord;
+    struct sockaddr_in socketaddr;
+    struct hostent *hostaddr;
+    struct servent *servaddr;
+    struct protoent *protocol;
+    char *p, *next;
+    int offset = 0;
+
+    /* get host name and format the get command */
+    get_args(web_url, host, get_cmd, &port, STR_LEN);
+
+    /* Resolve the host name */
+    if (!(hostaddr = gethostbyname(host))) {
+        fprintf(stderr, "Getting server list: error resolving host %s.", host);
+        return -1;
+    }
+
+    /* clear and initialize socketaddr */
+    memset(&socketaddr, 0, sizeof(socketaddr));
+    socketaddr.sin_family = AF_INET;
+
+    /* setup the servent struct using getservbyname */
+    servaddr              = getservbyname(SERVICE, PROTOCOL);
+    if (0 == port) {
+        socketaddr.sin_port = servaddr->s_port;
+    } else {
+        socketaddr.sin_port = htons(port);
+    }
+
+    memcpy(&socketaddr.sin_addr, hostaddr->h_addr, hostaddr->h_length);
+
+    /* protocol must be a number when used with socket()
+     * since we are using tcp protocol->p_proto will be 0 */
+    protocol = getprotobyname(PROTOCOL);
+
+    sockid   = socket(AF_INET, SOCK_STREAM, protocol->p_proto);
+    if (sockid < 0) {
+        fprintf(stderr, "get: error creating socket\n");
+        return -1;
+    }
+
+    /* everything is setup, now we connect */
+    if (connect(sockid, (struct sockaddr *) &socketaddr, sizeof(socketaddr)) 
== -1) {
+        fprintf(stderr, "get: error connecting\n");
+        nw_close(sockid);
+        return -1;
+    }
+
+    /* send our get request for http */
+    if (send(sockid, get_cmd, strlen(get_cmd), 0) == -1) {
+        fprintf(stderr, "get: error sending data\n");
+        nw_close(sockid);
+        return -1;
+    }
+
+    //printf ("8888:   start get\n");
+    /* read the socket until its clear then exit */
+    while ((bufsize = recv(sockid, buffer + offset, sizeof(buffer) - offset - 
1, 0))) {
+        if (bufsize == -1) {
+            I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL,
+                            "Error while getting list of i3 servers in 
get_addr: %s.\n",
+                            strerror(errno)
+                            );
+            break;
+        }
+
+        buffer[offset + bufsize] = 0;
+        p                        = buffer;
+
+        while ((next = strstr(p, "\n")) != NULL) {
+            if (get_entry(p, next, ip_addr, &port, id, &status,
+                          &(coord.latitude), &(coord.longitude))) {
+                if (status) {
+                    I3_PRINT_DEBUG5(I3_DEBUG_LEVEL_VERBOSE, "GET: %s %d %s 
%.1f %.1f\n",
+                                    ip_addr, port, id, coord.latitude, 
coord.longitude);
+                    update_i3server(list, ntohl(inet_addr(ip_addr)),
+                                    port, atoi3id(id), coord);
+                }
+            }
+            p = next + 1;
+        }
+
+        memmove(buffer, p, strlen(p));
+        offset = strlen(p);
+    }
+    //printf ("8888:   stop get\n");
+    nw_close(sockid);
+    return 0;
 }
 
 void update_i3_server_list(char *web_url, I3ServerList *list,
-                          I3ServerListNode **next_ping)
+                           I3ServerListNode **next_ping)
 {
     mark_i3servers_dead(list);
     if (get_address(web_url, list) >= 0) {
-       delete_dead_i3servers(list);
-       *next_ping = list->list;
+        delete_dead_i3servers(list);
+        *next_ping = list->list;
     }
 }

=== modified file 'i3/i3_client/http.h'
--- i3/i3_client/http.h 2009-12-11 22:49:11 +0000
+++ i3/i3_client/http.h 2010-02-11 11:49:47 +0000
@@ -4,6 +4,6 @@
 #include "i3server_list.h"
 
 void update_i3_server_list(char *web_url, I3ServerList *list,
-                          I3ServerListNode **next_ping);
+                           I3ServerListNode **next_ping);
 
 #endif

=== modified file 'i3/i3_client/i3_client.h'
--- i3/i3_client/i3_client.h    2010-01-06 22:17:32 +0000
+++ i3/i3_client/i3_client.h    2010-02-11 11:49:47 +0000
@@ -14,14 +14,14 @@
 #include "i3_client_fd.h"
 #include "../utils/event.h"
 
-#define CL_CBK_TRIGGER_INSERTED       1        
-#define CL_CBK_TRIGGER_REFRESH_FAILED 2        
+#define CL_CBK_TRIGGER_INSERTED       1
+#define CL_CBK_TRIGGER_REFRESH_FAILED 2
 #define CL_CBK_TRIGGER_NOT_FOUND      3
 #define CL_CBK_RECEIVE_PACKET         4
 #define CL_CBK_RECEIVE_PAYLOAD        5
 #define CL_CBK_SERVER_DOWN            6
 #define CL_CBK_TRIGGER_CONSTRAINT_FAILED 7
-#define CL_CBK_ROUTE_BROKEN          8
+#define CL_CBK_ROUTE_BROKEN           8
 #define CL_CBK_RATELIMIT_EXCEEDED     9
 
 
@@ -31,7 +31,7 @@
 #define CL_RET_OK                      0
 #define CL_RET_TRIGGER_ALREADY_CREATED 1
 #define CL_RET_TRIGGER_NOT_FOUND       2
-#define CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD 3   
+#define CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD 3
 #define CL_RET_DUP_CONTEXT             4
 #define CL_RET_NO_CONTEXT              5
 #define CL_RET_NO_TRIGGER              6
@@ -44,9 +44,9 @@
 #define CL_RET_INVALID_CFG_FILE       17
 #define CL_RET_INVALID_FLAGS          18
 #define CL_RET_INVALID_STACK_LEN      20
-#define CL_RET_NET_ERROR             21
-#define CL_RET_MSG_SIZE                      22
-#define CL_RET_NO_SERVERS            23
+#define CL_RET_NET_ERROR              21
+#define CL_RET_MSG_SIZE               22
+#define CL_RET_NO_SERVERS             23
 
 #define CL_TRIGGER_STATUS_IDLE   0
 #define CL_TRIGGER_STATUS_PENDING  1
@@ -77,147 +77,146 @@
 #define EOL          0xa
 #define MAX_BUF_SIZE 2048
 
-#define CL_HTABLE_SIZE 1024*64
+#define CL_HTABLE_SIZE 1024 * 64
 
 #define UMILLION 1000000ULL
 
 /****************************************************************************
- *  Macro definitions
- ****************************************************************************/
-
-#define CL_HASH_ID(id) (((*(uint32_t *)&(id)->x[0])^(*(uint32_t *)&(id)->x[4]) 
^ (*(uint32_t *)&(id)->x[8]) ^ (*(uint32_t *)&(id)->x[12]))% CL_HTABLE_SIZE)
-
-#define CL_HASH_TRIG(id) (((*(uint32_t *)&(id)->x[0])^(*(uint32_t 
*)&(id)->x[4])^ (*(uint32_t *)&(id)->x[8]) ^ (*(uint32_t *)&(id)->x[12]))% 
CL_HTABLE_SIZE)
+*  Macro definitions
+****************************************************************************/
+
+#define CL_HASH_ID(id) (((*(uint32_t *) &(id)->x[0]) ^ (*(uint32_t *) 
&(id)->x[4]) ^ (*(uint32_t *) &(id)->x[8]) ^ (*(uint32_t *) &(id)->x[12])) % 
CL_HTABLE_SIZE)
+
+#define CL_HASH_TRIG(id) (((*(uint32_t *) &(id)->x[0]) ^ (*(uint32_t *) 
&(id)->x[4]) ^ (*(uint32_t *) &(id)->x[8]) ^ (*(uint32_t *) &(id)->x[12])) % 
CL_HTABLE_SIZE)
 
 /* #define CL_HASH_TRIG(id) (((*(uint32_t *)&(id)->x[0])^(*(uint32_t 
*)&(id)->x[4])^ (*(uint32_t *)&(id)->x[8]) ^ (*(uint32_t *)&(id)->x[12]) ^ 
(*(uint32_t *)&(id)->x[16]) ^ (*(uint32_t *)&(id)->x[20]) ^ (*(uint32_t 
*)&(id)->x[24]) ^ (*(uint32_t *)&(id)->x[28]))% CL_HTABLE_SIZE) */
 
 
 /****************************************************************************
- *  Data structures
- ****************************************************************************/
+*  Data structures
+****************************************************************************/
 
 typedef struct buf_struct {
-  unsigned short  len;
-  char *p;
+    unsigned short len;
+    char *         p;
 } buf_struct;
 
 #ifndef CCURED
 typedef struct cl_cbk {
-  void (*fun)(void*, void*, void*);  /* pointer to callback function */
-  void *fun_ctx;     /* pointer to the function context information specified 
while registering the callback */
-
+    void (*fun)(void *, void *, void *); /* pointer to callback function */
+    void *fun_ctx;   /* pointer to the function context information specified 
while registering the callback */
 } cl_cbk;
 #else
 #ifndef __RTTI
   #define __RTTI
 #endif
 typedef struct cl_cbk {
-  void (*fun)(i3_trigger*, void * __RTTI);  /* pointer to callbcak function */
-  void * __RTTI fun_ctx;     /* pointer to the function context information 
specified while registering the callback */
+    void (*fun)(i3_trigger *, void *__RTTI); /* pointer to callbcak function */
+    void *__RTTI fun_ctx;    /* pointer to the function context information 
specified while registering the callback */
 } cl_cbk;
 #endif
 
 
 typedef struct cl_trigger {
-  i3_trigger        *t;
-  buf_struct         precomputed_pkt;
-  char               type; /* specify whether the trigger is inserted only 
-                            * locally (CL_TRIGGER_LOCAL) or is inserted in 
-                           * i3 (CL_TRIGGER_I3) 
+    i3_trigger *t;
+    buf_struct  precomputed_pkt;
+    char        type;      /* specify whether the trigger is inserted only
+                            * locally (CL_TRIGGER_LOCAL) or is inserted in
+                            * i3 (CL_TRIGGER_I3)
                             */
-  char              is_queued; /* true when it is inserted in PRIORITY QUEUE.
-                                * the priority queue is used to efficiently
+    char        is_queued;      /* true when it is inserted in PRIORITY QUEUE.
+                                 * the priority queue is used to efficiently
                                  * refresh triggers
                                  */
-  uint16_t           status; /* possible status: CL_TRIGGER_STATUS_PENDING, 
-                             * CL_TRIGGER_STATUS_INSERTED 
-                             * CL_TRIGGER_STATUS_IDLE 
+    uint16_t    status;      /* possible status: CL_TRIGGER_STATUS_PENDING,
+                              * CL_TRIGGER_STATUS_INSERTED
+                              * CL_TRIGGER_STATUS_IDLE
                               */
-  int                retries_cnt;
-  cl_cbk cbk_trigger_inserted; /* callback confirming that the trigger
-                               * has been inserted 
-                                */
-  cl_cbk cbk_trigger_refresh_failed;/* trigger cannot be inserted 
-                                    * or trigger couldn't be refreshed 
+    int         retries_cnt;
+    cl_cbk      cbk_trigger_inserted; /* callback confirming that the trigger
+                                       * has been inserted
+                                       */
+    cl_cbk      cbk_trigger_refresh_failed; /* trigger cannot be inserted
+                                             * or trigger couldn't be refreshed
+                                             */
+    cl_cbk      cbk_trigger_constraint_failed; /* constraint fails at server */
+    cl_cbk      cbk_receive_packet; /* callback triggered when a packet
+                                     * arrives to this trigger
                                      */
-  cl_cbk cbk_trigger_constraint_failed; /* constraint fails at server */
-  cl_cbk cbk_receive_packet;    /* callback triggered when a packet 
-                                * arrives to this trigger 
-                                 */
-  cl_cbk cbk_receive_payload;   /* callback triggered when a packet 
-                                * arrives to this trigger
-                                * NOTE 1: cbk_receive_packet has a higher
-                                * precedence than cbk_receive_data; if both
-                                * of these callbacks are specified, only 
-                                * cbk_receive_data will called
-                                * NOTE 2: the only difference between 
-                                * cbk_receive_data and cbk_receive_packet
-                                * is that cbk_receive_packet returns
-                                 * the packet's header (hdr) in addition 
-                                 */
-  cl_cbk cbk_route_broken;     /* triggered when an i3_server 
-                                * attempting to forward a packet
-                                * along this trigger discovers that
-                                * the i3_server corres to the next
-                                * hop is down 
-                                 */
-
-  /** This is an internal hook which is triggered whenever a trigger ack 
timeout
-    * needs to be set.  This is used only when an external select() statement
-    * is used (as in the proxy).
-    */
-  cl_cbk internal_hook_ack_timeout;
-
-  /** This is an internal hook which is triggered whenever a trigger refresh 
timeout
-    * needs to be set.  This is used only when an external select() statement
-    * is used (as in the proxy).
-    */
-  cl_cbk internal_hook_refresh_timeout;
-  
-  void  *ctx;                   /* trigger's context */
-  void  *timer;                 /* pointer to the current timeout associated
+    cl_cbk      cbk_receive_payload; /* callback triggered when a packet
+                                      * arrives to this trigger
+                                      * NOTE 1: cbk_receive_packet has a higher
+                                      * precedence than cbk_receive_data; if 
both
+                                      * of these callbacks are specified, only
+                                      * cbk_receive_data will called
+                                      * NOTE 2: the only difference between
+                                      * cbk_receive_data and cbk_receive_packet
+                                      * is that cbk_receive_packet returns
+                                      * the packet's header (hdr) in addition
+                                      */
+    cl_cbk cbk_route_broken;    /* triggered when an i3_server
+                                 * attempting to forward a packet
+                                 * along this trigger discovers that
+                                 * the i3_server corres to the next
+                                 * hop is down
+                                 */
+
+    /** This is an internal hook which is triggered whenever a trigger ack 
timeout
+     * needs to be set.  This is used only when an external select() statement
+     * is used (as in the proxy).
+     */
+    cl_cbk internal_hook_ack_timeout;
+
+    /** This is an internal hook which is triggered whenever a trigger refresh 
timeout
+     * needs to be set.  This is used only when an external select() statement
+     * is used (as in the proxy).
+     */
+    cl_cbk             internal_hook_refresh_timeout;
+
+    void *             ctx;     /* trigger's context */
+    void *             timer;   /* pointer to the current timeout associated
                                  * to the trigger (e.g., timeout)
-                                */
-  struct cl_trigger *next;
-  struct cl_trigger *prev;
+                                 */
+    struct cl_trigger *next;
+    struct cl_trigger *prev;
 } cl_trigger;
 
 
 typedef struct cl_id {
-  ID                 id;
-  struct sockaddr_in cache_addr; /* address where packets with the
-                                 * the identifier "id" are sent;
-                                  * data is stored in network format 
-                                 */
-  struct sockaddr_in dest_addr;  /* destination address. Returned
-                                  * by the I3_OPT_CACHE_DEST_ADDR and
-                                 * I3_OPT_CACHE_SHORTCUT_ADDR options
-                                 */
-  int            retries_cnt;     
-  struct timeval last_ack;  /* time when last request for ack 
-                              has been sent */
-  cl_cbk    cbk_no_trigger; /* callback invoked when no trigger
-                             * matching the "id" filed was found 
-                             */
+    ID                 id;
+    struct sockaddr_in cache_addr; /* address where packets with the
+                                    * the identifier "id" are sent;
+                                    * data is stored in network format
+                                    */
+    struct sockaddr_in dest_addr; /* destination address. Returned
+                                   * by the I3_OPT_CACHE_DEST_ADDR and
+                                   * I3_OPT_CACHE_SHORTCUT_ADDR options
+                                   */
+    int                retries_cnt;
+    struct timeval     last_ack; /* time when last request for ack
+                                  * has been sent */
+    cl_cbk             cbk_no_trigger; /* callback invoked when no trigger
+                                        * matching the "id" filed was found
+                                        */
 #if NEWS_INSTRUMENT
-  int          opt_log_pkt;
-  int          opt_add_ts;
+    int                opt_log_pkt;
+    int                opt_add_ts;
 #endif
-  struct cl_id *next;
-  struct cl_id *prev;
+    struct cl_id *     next;
+    struct cl_id *     prev;
 } cl_id;
 
 
 /* maintain the list of i3 servers read from the configuration file */
  #define MAX_NUM_SRV 20
 typedef struct srv_address {
-  struct in_addr addr;
-  uint16_t port;
-  ID id;
+    struct in_addr addr;
+    uint16_t       port;
+    ID             id;
 #define ID_EMPTY 0
 #define ID_UP    1
 #define ID_DOWN  2
-  char     status;
+    char           status;
 } srv_address;
 
 /* Maintain array of precomputed options */
@@ -228,96 +227,95 @@
 #define REFRESH_SHORTCUT_MASK (1 << 3)
 
 typedef struct {
-  nw_skt_t                fd;    /* file descriptor for i3 packets */
-  struct sockaddr_in local; /* local address, used to receive i3 traffic 
-                            * (in network format)
-                            */
-  struct in_addr local_ip_addr; /* local IP address; this field is
-                                * needed because the IP address in 
-                                * "local" data structure is set to
-                                * INADDR_ANY (host format)
-                                */
-  uint16_t        local_port; /* local port number (host format) */           
-  struct timeval  now; /* updated every time cl_refresh_context 
-                       * is invoked */
-
-  nw_skt_t     tcp_fd;         /* Filedes for TCP connection */
-  char         is_tcp;         /* 1 if tcp connection is used */
-  
-  cl_cbk cbk_trigger_not_found;  /* callback invoked when there is no trigger
-                                  * matching the ID of the transmitted 
-                                  * packet */ 
-  cl_cbk cbk_server_down;        /* callback invoked when an i3 server
-                                 * couldn't be contacted */ 
-  /* following callbacks are called when the corresponding callbacks 
-   * associated with the trigger are not defined */
-  cl_cbk cbk_trigger_inserted; /* callback confirming that the trigger
-                               * has been inserted 
-                               */
-  cl_cbk cbk_trigger_refresh_failed;/* trigger cannot be inserted 
-                                    * or trigger couldn't be refreshed */
-  cl_cbk cbk_trigger_constraint_failed; /* constraint fails at server */
-    
-  cl_cbk cbk_receive_packet;    /* callback triggered when a packet 
-                                * arrives to this trigger */
-  cl_cbk cbk_receive_payload;   /* callback triggered when a packet 
-                                * arrives to this trigger
-                                * NOTE 1: cbk_receive_packet has a higher
-                                * precedence than cbk_receive_data; if both
-                                * of these callbacks are specified, only 
-                                * cbk_receive_data will called
-                                * NOTE 2: the only difference between 
-                                * cbk_receive_data and cbk_receive_packet
-                                * is that cbk_receive_packet returns
-                                 * the packet's header (hdr) in addition */
-  cl_cbk cbk_route_broken;     /* triggered when an i3_server when
-                                  attempting to forward a packet
-                                  along this trigger discovers that
-                                  the i3_server corres to the next
-                                  hop is down */
-  
-  cl_cbk cbk_ratelimit_exceeded; /* callback invoked when the token-bucket
-                                 * constraints of trigger that matches the
-                                 * packet's ID are exceeded
-                                 */
-  cl_trigger      *trigger_htable[CL_HTABLE_SIZE];
-  cl_id           *id_htable[CL_HTABLE_SIZE];
-  srv_address     *s_array;
-  int            num_servers;
-  buf_struct     precomputed_opt[MAX_OPTS_MASK_SIZE];
-  I3ServerList *list;
-  EventHeap       timer_heap; /* heap managing timers */
+    nw_skt_t           fd;       /* file descriptor for i3 packets */
+    struct sockaddr_in local; /* local address, used to receive i3 traffic
+                               * (in network format)
+                               */
+    struct in_addr     local_ip_addr; /* local IP address; this field is
+                                       * needed because the IP address in
+                                       * "local" data structure is set to
+                                       * INADDR_ANY (host format)
+                                       */
+    uint16_t       local_port; /* local port number (host format) */
+    struct timeval now; /* updated every time cl_refresh_context
+                         * is invoked */
+
+    nw_skt_t       tcp_fd;      /* Filedes for TCP connection */
+    char           is_tcp;      /* 1 if tcp connection is used */
+
+    cl_cbk         cbk_trigger_not_found; /* callback invoked when there is no 
trigger
+                                           * matching the ID of the transmitted
+                                           * packet */
+    cl_cbk         cbk_server_down; /* callback invoked when an i3 server
+                                     * couldn't be contacted */
+    /* following callbacks are called when the corresponding callbacks
+     * associated with the trigger are not defined */
+    cl_cbk         cbk_trigger_inserted; /* callback confirming that the 
trigger
+                                          * has been inserted
+                                          */
+    cl_cbk         cbk_trigger_refresh_failed; /* trigger cannot be inserted
+                                                * or trigger couldn't be 
refreshed */
+    cl_cbk         cbk_trigger_constraint_failed; /* constraint fails at 
server */
+
+    cl_cbk         cbk_receive_packet; /* callback triggered when a packet
+                                        * arrives to this trigger */
+    cl_cbk         cbk_receive_payload; /* callback triggered when a packet
+                                         * arrives to this trigger
+                                         * NOTE 1: cbk_receive_packet has a 
higher
+                                         * precedence than cbk_receive_data; 
if both
+                                         * of these callbacks are specified, 
only
+                                         * cbk_receive_data will called
+                                         * NOTE 2: the only difference between
+                                         * cbk_receive_data and 
cbk_receive_packet
+                                         * is that cbk_receive_packet returns
+                                         * the packet's header (hdr) in 
addition */
+    cl_cbk cbk_route_broken;    /* triggered when an i3_server when
+                                 * attempting to forward a packet
+                                 * along this trigger discovers that
+                                 * the i3_server corres to the next
+                                 * hop is down */
+
+    cl_cbk        cbk_ratelimit_exceeded; /* callback invoked when the 
token-bucket
+                                           * constraints of trigger that 
matches the
+                                           * packet's ID are exceeded
+                                           */
+    cl_trigger *  trigger_htable[CL_HTABLE_SIZE];
+    cl_id *       id_htable[CL_HTABLE_SIZE];
+    srv_address * s_array;
+    int           num_servers;
+    buf_struct    precomputed_opt[MAX_OPTS_MASK_SIZE];
+    I3ServerList *list;
+    EventHeap     timer_heap; /* heap managing timers */
 #define MAX_FDS 1024
-  i3_fds         *i3fds; /* list of file descriptors */
-  uint64_t *ping_start_time;
-
-  /** Is pinging being used to choose the best i3 server
-   * 0 - no
-   * 1 - true
-   */
-  unsigned short use_ping;
-
-  /** TCP socket was successfully initialized if this flag is 1.
-    * Else the flag is 0.
-    */
-  int init_tcp_ctx_flag;
-  
+    i3_fds *      i3fds; /* list of file descriptors */
+    uint64_t *    ping_start_time;
+
+    /** Is pinging being used to choose the best i3 server
+     * 0 - no
+     * 1 - true
+     */
+    unsigned short use_ping;
+
+    /** TCP socket was successfully initialized if this flag is 1.
+     * Else the flag is 0.
+     */
+    int init_tcp_ctx_flag;
 } cl_context;
 
 
-/* this data structure is used to send/receive data while eliminating 
+/* this data structure is used to send/receive data while eliminating
  * an extra memory copy
  */
 typedef struct cl_buf {
 #define CL_PREFIX_LEN   512
-  char *data;            /* pointer to the payload */
-  unsigned int data_len; /* length of the payload */
-  unsigned int max_len;  /* maximum length that can be used for payload */
-  char *internal_buf;    /* pointer to the allocated buffer. the size of 
-                          * this buffer is max_len + 2*CL_PREFIX_LEN.
-                         * the "data" pointer is between (internal_buf + 
-                         * CL_PREFIX_LEN) and (internal_buf + 2*CL_PREFIX_LEN)
-                         */
+    char *       data;   /* pointer to the payload */
+    unsigned int data_len; /* length of the payload */
+    unsigned int max_len; /* maximum length that can be used for payload */
+    char *       internal_buf; /* pointer to the allocated buffer. the size of
+                                * this buffer is max_len + 2*CL_PREFIX_LEN.
+                                * the "data" pointer is between (internal_buf +
+                                * CL_PREFIX_LEN) and (internal_buf + 
2*CL_PREFIX_LEN)
+                                */
 } cl_buf;
 
 

=== modified file 'i3/i3_client/i3_client_api.c'
--- i3/i3_client/i3_client_api.c        2010-01-06 22:17:32 +0000
+++ i3/i3_client/i3_client_api.c        2010-02-11 11:49:47 +0000
@@ -1,9 +1,9 @@
 /***************************************************************************
-                          i3_client_api.c  -  description
-                             -------------------
-    begin                : Aug 20 2003
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
+*                         i3_client_api.c  -  description
+*                            -------------------
+*   begin                : Aug 20 2003
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
 
 
 #include <errno.h>
@@ -26,12 +26,12 @@
  * This structure stores all i3 specific information.
  * By default, all API functions use g_ctx.  Moreover, you can have only one 
g_ctx
  * structure in a program as it is static.
- * 
+ *
  * If you wish to use a different instance of the context, rather
- * than the one defined here, the functions in i3_client_api_ctx will be 
+ * than the one defined here, the functions in i3_client_api_ctx will be
  * helpful.  Those function explicitly take a cl_context structure as one
  * of their inputs.
- */ 
+ */
 static cl_context *g_ctx = NULL; /* context associated with the process */
 
 /************************************************************************
@@ -43,107 +43,106 @@
  * calling any other I3 API functions.
  *
  * @param cfg_file The i3 configuration file from which parameters are read.
- * 
+ *
  * @return One of the following error codes is returned.
- *         <ul>
+ *        <ul>
  *               <li><code>CL_RET_OK</code> - Initialization was completed 
successfully.
  *               <li><code>CL_RET_INVALID_CFG_FILE</code> - There was an error 
in the supplied configuration file.
  *               <li><code>CL_RE_NO_CONTEXT</code> - Unable to initialize the 
context.
  *               <li><code>CL_RET_DUP_CONTEXT</code> - I3 was already 
initialized previously.
- *              <li><code>CL_RET_NET_ERROR</code> - networking subsystem could 
not be initialized.
- *                                 You shouldn't call this function multiple 
times.
- *         </ul>
+ *         <li><code>CL_RET_NET_ERROR</code> - networking subsystem could not 
be initialized.
+ *                    You shouldn't call this function multiple times.
+ *        </ul>
  */
 int cl_init(char *cfg_file)
 {
-  int rc;
-
-  init_rand();
-
-  if (0 != nw_init())
-      return CL_RET_NET_ERROR;
-
-  if (g_ctx != NULL)
-    return CL_RET_DUP_CONTEXT;
-  
-  g_ctx = cl_ctx_init(cfg_file, &rc, 0);
-
-  return rc;
+    int rc;
+
+    init_rand();
+
+    if (0 != nw_init()) {
+        return CL_RET_NET_ERROR;
+    }
+
+    if (g_ctx != NULL) {
+        return CL_RET_DUP_CONTEXT;
+    }
+
+    g_ctx = cl_ctx_init(cfg_file, &rc, 0);
+
+    return rc;
 }
 
-
 /**
  * This function is called to free all resources allocated by
  * cl_init().  This function is usually called when you are exiting the 
program.
- * 
+ *
  * @return One of the following error codes is returned.
- *         <ul>
- *             <li><code>CL_RET_OK</code> - All resources were successfully 
freed.
- *             <li><code>CL_RET_NO_CONTEXT</code> - There was no i3 context to 
free.  
- *             This error usually occurs when a cl_init() was initially 
omitted.
- *         </ul>
+ *        <ul>
+ *        <li><code>CL_RET_OK</code> - All resources were successfully freed.
+ *        <li><code>CL_RET_NO_CONTEXT</code> - There was no i3 context to free.
+ *        This error usually occurs when a cl_init() was initially omitted.
+ *        </ul>
  */
 int cl_exit()
 {
-  int rc;
+    int rc;
 
-  rc = cl_ctx_exit(g_ctx);
-  g_ctx = NULL;
-  return rc;
+    rc    = cl_ctx_exit(g_ctx);
+    g_ctx = NULL;
+    return rc;
 }
 
-
 /************************************************************************
- * cl_selct - function that replaces the select() function 
- *            (sys/select.h) Either this function or cl_loop() should be 
- *            invoked at the end of every client program since 
- *            cl_select()/cl_loop() are responsibe with the trigger 
+ * cl_selct - function that replaces the select() function
+ *            (sys/select.h) Either this function or cl_loop() should be
+ *            invoked at the end of every client program since
+ *            cl_select()/cl_loop() are responsibe with the trigger
  *            refreshing and processing the options of the received packets.
  ***********************************************************************/
 /**
  * This function should be called in the client program after all 
initialization
  * has been completed.
- * This function loops indefinitely and does not return unless there is an 
- * error.  It listens for packets on the i3 socket and other sockets added 
- * using cl_register_fd_callback(). 
+ * This function loops indefinitely and does not return unless there is an
+ * error.  It listens for packets on the i3 socket and other sockets added
+ * using cl_register_fd_callback().
  */
-int cl_select(int n, fd_set *readfds, fd_set *writefds, 
-             fd_set *exceptfds, struct timeval *cl_to)
+int cl_select(int n, fd_set *readfds, fd_set *writefds,
+              fd_set *exceptfds, struct timeval *cl_to)
 {
-  if (g_ctx == NULL)
-    return CL_RET_NO_CONTEXT; 
-  return cl_ctx_select(g_ctx, n, readfds, writefds, exceptfds, cl_to); /*xxx */
+    if (g_ctx == NULL) {
+        return CL_RET_NO_CONTEXT;
+    }
+    return cl_ctx_select(g_ctx, n, readfds, writefds, exceptfds, cl_to); /*xxx 
*/
 }
 
-
 int cl_loop(void)
 {
-  return cl_ctx_loop(g_ctx);
+    return cl_ctx_loop(g_ctx);
 }
 
-
 /**
  * This function is used to create a trigger which points to the client,
- * i.e. the machine on which this function is executed.  
+ * i.e. the machine on which this function is executed.
  * Please note that this function does not insert the trigger into the i3 
infrastructure.
  * <code>cl_insert_trigger</code> is used to insert the trigger into the i3 
infrastructure.
- * 
+ *
  * @param id The i3 Id of the trigger to be created.
- * 
+ *
  * @param prefix_len The length of the prefix of the id to be used for 
matching.
- * 
+ *
  * @param key The key for this trigger. <br>
- *              The key is equal to h_l(id) if the trigger is left 
constrained, and<br>
+ *         The key is equal to h_l(id) if the trigger is left constrained, 
and<br>
  *               h_r(id) if the trigger is right constrained, <br>
  *               where h_l and h_r are two one-way hash functions.
- *              The key field of the ID is upadted to h_l(key) or h_r(key).
- *              
+ *             The key field of the ID is upadted to h_l(key) or h_r(key).
+ *
  * @param flags Flags are used to specify the properties of the trigger being 
created.
  * The following flags can be used individually or ORed together.
  * <ul>
- *     <li><code>CL_TRIGGER_CFLAG_R_CONSTRAINT</code> - Make the trigger right 
constrained.
+ *    <li><code>CL_TRIGGER_CFLAG_R_CONSTRAINT</code> - Make the trigger right 
constrained.
  *      <li><code>CL_TRIGGER_CFLAG_L_CONSTRAINT</code> - Make the trigger left 
constrained.
- *      <li><code>CL_TRIGGER_CFLAG_PUBLIC</code> - Make this a public trigger. 
 If this is flag is 
+ *      <li><code>CL_TRIGGER_CFLAG_PUBLIC</code> - Make this a public trigger. 
 If this is flag is
  *      not used, the trigger is private by default.  Please note that a 
public trigger must be left constrained.
  *      This means that you cannot use the flags 
<code>CL_TRIGGER_CFLAG_R_CONSTRAINT</code> and
  *      CL_TRIGGER_CFLAG_PUBLIC together.
@@ -153,135 +152,131 @@
  *      the id by calling set_public_id before using it.  The same applies to 
CL_TRIGGER_CFLAG_PRIVATE too (Note
  *      that CL_TRIGGER_CFLAG_PRIVATE is assumed by default unless 
CL_TRIGGER_CLFAG_PUBLIC is specified.)
  * </ul>
- * 
+ *
  * @return A pointer to the created trigger.
  */
-cl_trigger *cl_create_trigger(ID *id, uint16_t prefix_len, Key *key, 
-                             uint16_t flags)
+cl_trigger *cl_create_trigger(ID *id, uint16_t prefix_len, Key *key,
+                              uint16_t flags)
 {
-  int rc;
-  return cl_ctx_create_trigger(g_ctx, id, prefix_len, key, flags, &rc);
+    int rc;
+    return cl_ctx_create_trigger(g_ctx, id, prefix_len, key, flags, &rc);
 }
 
-
 /**
  * This function is similar to cl_create_trigger except that the created
- * trigger points to the specificed stack of i3 IDs instead of the 
+ * trigger points to the specificed stack of i3 IDs instead of the
  * client machine.
  *
  * Please note that this function does not insert the trigger into the i3 
infrastructure.
  * <code>cl_insert_trigger</code> is used to insert the trigger into the i3 
infrastructure.
  *
  * @param id The i3 Id of the trigger to be created.
- * 
+ *
  * @param prefix_len The length of the prefix of the id to be used for 
matching.
- * 
- * @param stack        The stack of i3 ids to which this trigger points
+ *
+ * @param stack    The stack of i3 ids to which this trigger points
  * @param stack_len The number of i3 ids in the stack.
- * 
+ *
  * @param flags Flags are used to specify the properties of the trigger being 
created.
  * The following flags can be used individually or ORed together.
  * <ul>
- *     <li><code>CL_TRIGGER_CFLAG_R_CONSTRAINT</code> - Make the trigger right 
constrained.
+ *    <li><code>CL_TRIGGER_CFLAG_R_CONSTRAINT</code> - Make the trigger right 
constrained.
  *      <li><code>CL_TRIGGER_CFLAG_L_CONSTRAINT</code> - Make the trigger left 
constrained.
- *      <li><code>CL_TRIGGER_CFLAG_PUBLIC</code> - Make this a public trigger. 
 If this is flag is 
+ *      <li><code>CL_TRIGGER_CFLAG_PUBLIC</code> - Make this a public trigger. 
 If this is flag is
  *      not used, the trigger is private by default.  Please note that a 
public trigger must be left constrained.
  *      This means that you cannot use the flags 
<code>CL_TRIGGER_CFLAG_R_CONSTRAINT</code> and
  *      CL_TRIGGER_CFLAG_PUBLIC together.
  * </ul>
- * 
+ *
  * @return A pointer to the created trigger.
  */
-cl_trigger *cl_create_trigger_stack(ID *id, uint16_t prefix_len, 
-                                   ID *stack, int stack_len, 
-                                   uint16_t flags)
+cl_trigger *cl_create_trigger_stack(ID *id, uint16_t prefix_len,
+                                    ID *stack, int stack_len,
+                                    uint16_t flags)
 {
-  int rc;
-  return cl_ctx_create_trigger_stack(g_ctx, id, prefix_len, stack, 
-                                    stack_len, flags, &rc);
+    int rc;
+    return cl_ctx_create_trigger_stack(g_ctx, id, prefix_len, stack,
+                                       stack_len, flags, &rc);
 }
 
-
 /**
  * This function is used to deallocate a trigger created by
- * <code>cl_create_trigger.  This function not only frees up 
+ * <code>cl_create_trigger.  This function not only frees up
  * the memory used by the trigger in the local system, but also
  * removes it from the i3 infrastructure.
  *
  * @param ctr Pointer to the trigger to be destroyed.
  *
  * @return One of the following codes is returned.
- *     <ul>
- *         <li><code>CL_RET_OK</code> - The trigger was successfully destroyed.
- *         <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
- *         invalid context. Probably cl_init() was not called initially.
- *     </ul>
+ *    <ul>
+ *        <li><code>CL_RET_OK</code> - The trigger was successfully destroyed.
+ *        <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
+ *        invalid context. Probably cl_init() was not called initially.
+ *    </ul>
  */
 int cl_destroy_trigger(cl_trigger *ctr)
 {
-  return cl_ctx_destroy_trigger(g_ctx, ctr);
+    return cl_ctx_destroy_trigger(g_ctx, ctr);
 }
 
-
 /**
- * This function inserts the specified trigger into the i3 
+ * This function inserts the specified trigger into the i3
  * infrastructure.
  *
  * @param ctr Pointer to the trigger to be inserted.
  * @param flags The following flags can be specified at trigger insertion.
- *     <ul>
- *         <li><code>CL_IFLAGS_TRIGGER_LOCAL</code> - This trigger should be 
inserted locally, i.e. not
- *         in the i3 infrastructure.
- *         <li><code>CL_IFLAGS_TRIGGER_ALLOW_SHORTCUT</code> - This trigger 
allows shortcuts.
- *     </ul>
+ *    <ul>
+ *        <li><code>CL_IFLAGS_TRIGGER_LOCAL</code> - This trigger should be 
inserted locally, i.e. not
+ *        in the i3 infrastructure.
+ *        <li><code>CL_IFLAGS_TRIGGER_ALLOW_SHORTCUT</code> - This trigger 
allows shortcuts.
+ *    </ul>
  * @return One of the following codes is returned.
- *     <ul>
- *         <li><code>CL_RET_OK</code> - The trigger was successfully submitted 
for insertion.
- *         The trigger insertion callbacks (if any were registered) will be 
executed when 
- *         a confirmation message for trigger insertion is received from the 
infrastructure.
- *         
- *         <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
- *         invalid context. Probably cl_init() was not called initially.
- *
- *         <li><code>CL_RET_NO_TRIGGER</code> - The trigger to be inserted is 
NULL.
- *     </ul>
+ *    <ul>
+ *        <li><code>CL_RET_OK</code> - The trigger was successfully submitted 
for insertion.
+ *        The trigger insertion callbacks (if any were registered) will be 
executed when
+ *        a confirmation message for trigger insertion is received from the 
infrastructure.
+ *
+ *        <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
+ *        invalid context. Probably cl_init() was not called initially.
+ *
+ *        <li><code>CL_RET_NO_TRIGGER</code> - The trigger to be inserted is 
NULL.
+ *    </ul>
  */
-int cl_insert_trigger(cl_trigger *ctr, uint16_t flags) 
+int cl_insert_trigger(cl_trigger *ctr, uint16_t flags)
 {
-  return cl_ctx_insert_trigger(g_ctx, ctr, flags);
+    return cl_ctx_insert_trigger(g_ctx, ctr, flags);
 }
 
 /**
  * This function removes the specified trigger from the i3 infrastructure.
  * However, it is not destroyed from the local system, i.e. its data structures
- * are not deallocated.  It can be reinserted at a later point using 
+ * are not deallocated.  It can be reinserted at a later point using
  * <code>cl_insert_trigger</code>.
  *
  * @param ctr The trigger to be removed.
  *
  * @return One of the following codes is returned.
- *     <ul>
- *         <li><code>CL_RET_OK</code> - The trigger was successfully submitted 
for removal.
- *         
- *         <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
- *         invalid context. Probably cl_init() was not called initially.
- *
- *         <li><code>CL_RET_NO_TRIGGER</code> - The trigger to be removed is 
NULL.
- *     </ul>
+ *    <ul>
+ *        <li><code>CL_RET_OK</code> - The trigger was successfully submitted 
for removal.
+ *
+ *        <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
+ *        invalid context. Probably cl_init() was not called initially.
+ *
+ *        <li><code>CL_RET_NO_TRIGGER</code> - The trigger to be removed is 
NULL.
+ *    </ul>
  */
 int cl_remove_trigger(cl_trigger *ctr)
 {
-  return cl_ctx_remove_trigger(g_ctx, ctr);
+    return cl_ctx_remove_trigger(g_ctx, ctr);
 }
 
-
 /**
- * This function limits the traffic forwarded by a trigger using 
- * token-bucket constraints. 
+ * This function limits the traffic forwarded by a trigger using
+ * token-bucket constraints.
  *
  * Note 1: This function takes action only if/when the trigger
- * is inserted in the i3 infrastructure. If the trigger is local 
- * (i.e. it was inserted using the 
+ * is inserted in the i3 infrastructure. If the trigger is local
+ * (i.e. it was inserted using the
  * <li><code>CL_IFLAGS_TRIGGER_LOCAL</code></li> flag) this function
  * has no effect.
  *
@@ -292,9 +287,9 @@
  *
  * @param ctr The trigger to be rate limited using a token bucket.
  *
- * @param type The type of token bucket, specifying data units. 
-               Possible values are  TOKEN_BUKET_PACKET and  
-               TOKEN_BUKET_BYTE, respectively.
+ * @param type The type of token bucket, specifying data units.
+ *             Possible values are  TOKEN_BUKET_PACKET and
+ *             TOKEN_BUKET_BYTE, respectively.
  *
  * @param depth Token bucket depth (bytes or packets, depending on "type")
  *
@@ -303,224 +298,224 @@
  * @param R Token bucket peek rate (Bps or pps)
  *
  * @return One of the following codes is returned.
- *     <ul>
- *         <li><code>CL_RET_OK</code> - The trigger was successfully submitted 
for removal.
- *         
- *         <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
- *         invalid context. Probably cl_init() was not called initially.
- *
- *         <li><code>CL_RET_NO_TRIGGER</code> - The trigger does not exist.
- *     </ul>
+ *    <ul>
+ *        <li><code>CL_RET_OK</code> - The trigger was successfully submitted 
for removal.
+ *
+ *        <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
+ *        invalid context. Probably cl_init() was not called initially.
+ *
+ *        <li><code>CL_RET_NO_TRIGGER</code> - The trigger does not exist.
+ *    </ul>
  */
 int cl_trigger_ratelimit(cl_trigger *ctr, uint8_t type,
-                         uint32_t depth, uint32_t r, uint32_t R)
+                         uint32_t depth, uint32_t r, uint32_t R)
 {
-  return cl_ctx_trigger_ratelimit(g_ctx, ctr, type, depth, r, R);
+    return cl_ctx_trigger_ratelimit(g_ctx, ctr, type, depth, r, R);
 }
 
 /**
-    This function is used to register a callback associated with the current 
context.  This
-    is more general than associating a callback with a particular trigger. 
- 
-    @param cbk_type The callback type.  It should be equal to one of the 
following values:
-    <ol>
-    
-        <li><b>CL_CBK_TRIGGER_INSERTED</b> : This callback is invoked when the 
client receives the first ack as a result of a trigger insertion. 
-        
-        <li><b>CL_CBK_TRIGGER_REFRESH_FAILED</b> : This callback is invoked 
when the refreshing of a trigger fails. A refreshing failure occurs when none 
of the client's refreshing messages is acked during a refresh period which has 
a duration of TRIGGER_REFRESH_PERIOD sec. The client refreshes a trigger by 
sending a refreshing message MAX_NUM_TRIG_RETRIES*ACK_TIMEOUT before the 
refreshing period expires. If the first refresh message is not acked, the 
client resends the refresh message approximately every ACK_TIMEOUT sec.  A 
typical response of the client to this callback is to reinsert the trigger.
-    
-        <li><b>CL_CBK_TRIGGER_NOT_FOUND</b> : This callback is invoked when 
the client sends packets to an ID id, and there is no trigger in the network 
matching this id.
-
-        <li><b>CL_CBK_RATELIMIT_EXCEEDED</b> : This callback is invoked when 
the client packet (sent to an ID id) is dropped due to the violation of the 
token-bucket traffic constraints (associated with the trigger whose ID is id). 
-
- is no trigger in the network matching this id.
-
-        <li><b>CL_CBK_TRIGGER_CONSTRAINT_FAILED</b> : This callback invoked 
when an unconstrained trigger insertion is attempted.
-
-        <li><b>CL_CBK_RECEIVE_PACKET</b> : This callback is invoked on 
receiving an i3 packet.
-
-        <li><b>CL_CBK_RECEIVE_PAYLOAD</b> : This callback is invoked upon 
receiving a data packet. This callback is suppressed by the 
CL_CBK_RECEIVE_PACKET callback.
-        
-        <li><b>CL_CBK_SERVER_DOWN</b> : This callback is invoked when  the 
client concludes than an i3 server is down. This happens when the client either 
receives no acks (in the form of I3_OPT_CACHE_ADDR replies) to sending packets 
to that server during a refresh period of ID_REFRESH_PERIOD sec, or when the 
client receives no acks to three consecutive I3_OPT_REQUEST_FOR_CACHE queries.
-       
-        <li><b>CL_CBK_ROUTE_BROKEN</b> : This callback is invoked when server 
indicates that the i3server corresponding to the next hop is dead, and some 
action is needed to recover.
-    </ol> 
-    
-    @param fun   The pointer to the function to be executed when the callback 
is invoked.
-    This function pointer should point to a function with following 
signature:<br>
-    
-    <center><code>void funName (void *ctx_data, void *data, void 
*fun_ctx)</code></center>
-    
-    The parameters to the callback function are used as follows:
-  
-    <ul>
-    
-        <li><b>ctx_data</b>: This is parameter is used to pass some context 
info when the callback is invoked.  For example, for a callback of type 
CL_CBK_TRIGGER_INSERTED, the pointer to the <code>cl_trigger</code> which was 
inserted is passed via this argument.  Please note that the function signature 
must assign the type <code>void *</code> to this argument.  The argument must 
be appropriately cast before use inside the function body.
-
-        <li><b>data</b>: This parameter is used to pass back some data which 
is generated at the time of callback invocation.
-        For example, in the callback of type CL_CBK_RECEIVE_PAYLOAD, the 
payload of the packet received is passed through this argument.
-
-        <li><b>fun_ctx</b>:  This parameter is used to pass back data which 
was stored at the time of callback registration.
-
-    </ul>
- 
-    We now describe the values passed via the arguments of the callback 
function for the different callback types in the following table.
-
-    <table>
-        <tr>
-            <td>CALLBACK TYPE</td>
-            <td>ctx_data</td>
-            <td>data</td>
-            <td>fun_ctx</td>
-        </tr>
-        
-        <tr>
-            <td>CL_CBK_TRIGGER_INSERTED</td>
-            <td><code>cl_trigger* t</code>, where t represents the inserted 
trigger</td>
-            <td><code>NULL</code>
-            <td>function context passed at callback registration</td>
-        </tr>
- 
-        <tr>
-            <td>CL_CBK_TRIGGER_REFRESH_FAILED</td>
-            <td><code>cl_trigger* t</code>, where t represents the trigger 
whose refresh failed</td>
-            <td><code>NULL</code>
-            <td>function context passed at callback registration</td>
-        </tr>
-    
-        <tr>
-            <td>CL_CBK_TRIGGER_NOT_FOUND</td>
-            <td><code>ID *id</code>, the id for which no matching trigger was 
found.</td>
-            <td><code>NULL</code></td>
-            <td>function context passed at callback registration</td>
-        </tr>
-        
-        <tr>
-            <td>CL_CBK_RATELIMIT_EXCEEDED</td>
-            <td><code>ID *id</code>, the id whose token-bucket traffic 
constraints were violated.</td>
-            <td><code>NULL</code></td>
-            <td>function context passed at callback registration</td>
-        </tr>
-        
-        <tr>
-            <td>CL_CBK_TRIGGER_CONSTRAINT_FAILED</td>
-            <td><code>ID *id</code>, the id for which trigger constraint 
failed.</td>
-            <td><code>NULL</code></td>
-            <td>function context passed at callback registration</td>
-        </tr>
-        
-        <tr>
-            <td>CL_CBK_RECEIVE_PACKET</td>
-            <td><code>cl_trigger* t</code>, the trigger matching the packet's 
ID</td>
-            <td><code>cbk_packet* pkt</code> encapsulates the header and 
payload of the received packet.
-                Please note that the callback function should deallocate the 
memory pointed to by pkt after
-                it is no longer needed by using <code>free(pkt)</code>.  This 
frees up only the temporary encapsulating
-                cbk_packet and not the actual contents of the packet.</td>
-            <td>function context passed at callback registration</td>
-        </tr>
-        
-        <tr>
-            <td>CL_CBK_RECEIVE_PAYLOAD</td>
-            <td><code>cl_trigger* t</code>, the trigger matching the packet's 
ID</td>
-            <td><code>cl_buf *b</code>, the payload of the data packet 
received</td>
-            <td>function context passed at callback registration</td>
-        </tr>
- 
-        <tr>
-            <td>CL_CBK_SERVER_DOWN</td>
-            <td><code>struct in_addr *ip_addr</code>, the IP address of the 
server which is down</td>
-            <td><code>uint16_t *portNum</code>, the port on which i3 was 
supposed to have been running on the down server (TODO: It will better to 
aggregate the IP address and port info into a single structure as part of the 
first param.)</td>
-            <td>function context passed at callback registration</td>
-        </tr>
- 
-        <tr>
-            <td>CL_CBK_ROUTE_BROKEN</td>
-            <td><code>cl_trigger *t</code>, the trigger whose route has been 
broken [[VERIFY: unclear]]</td>
-            <td><code>NULL</code></td>
-            <td>function context passed at callback registration</td>
-        </tr>
-    </table>
- 
-  @return One of the following codes is returned.
-       <ul>
-           <li><code>CL_RET_OK</code> 
-           
-           <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
-           invalid context. Probably cl_init() was not called initially.
- 
-       </ul>
+ *  This function is used to register a callback associated with the current 
context.  This
+ *  is more general than associating a callback with a particular trigger.
+ *
+ *  @param cbk_type The callback type.  It should be equal to one of the 
following values:
+ *  <ol>
+ *
+ *      <li><b>CL_CBK_TRIGGER_INSERTED</b> : This callback is invoked when the 
client receives the first ack as a result of a trigger insertion.
+ *
+ *      <li><b>CL_CBK_TRIGGER_REFRESH_FAILED</b> : This callback is invoked 
when the refreshing of a trigger fails. A refreshing failure occurs when none 
of the client's refreshing messages is acked during a refresh period which has 
a duration of TRIGGER_REFRESH_PERIOD sec. The client refreshes a trigger by 
sending a refreshing message MAX_NUM_TRIG_RETRIES*ACK_TIMEOUT before the 
refreshing period expires. If the first refresh message is not acked, the 
client resends the refresh message approximately every ACK_TIMEOUT sec.  A 
typical response of the client to this callback is to reinsert the trigger.
+ *
+ *      <li><b>CL_CBK_TRIGGER_NOT_FOUND</b> : This callback is invoked when 
the client sends packets to an ID id, and there is no trigger in the network 
matching this id.
+ *
+ *      <li><b>CL_CBK_RATELIMIT_EXCEEDED</b> : This callback is invoked when 
the client packet (sent to an ID id) is dropped due to the violation of the 
token-bucket traffic constraints (associated with the trigger whose ID is id).
+ *
+ * is no trigger in the network matching this id.
+ *
+ *      <li><b>CL_CBK_TRIGGER_CONSTRAINT_FAILED</b> : This callback invoked 
when an unconstrained trigger insertion is attempted.
+ *
+ *      <li><b>CL_CBK_RECEIVE_PACKET</b> : This callback is invoked on 
receiving an i3 packet.
+ *
+ *      <li><b>CL_CBK_RECEIVE_PAYLOAD</b> : This callback is invoked upon 
receiving a data packet. This callback is suppressed by the 
CL_CBK_RECEIVE_PACKET callback.
+ *
+ *      <li><b>CL_CBK_SERVER_DOWN</b> : This callback is invoked when  the 
client concludes than an i3 server is down. This happens when the client either 
receives no acks (in the form of I3_OPT_CACHE_ADDR replies) to sending packets 
to that server during a refresh period of ID_REFRESH_PERIOD sec, or when the 
client receives no acks to three consecutive I3_OPT_REQUEST_FOR_CACHE queries.
+ *
+ *      <li><b>CL_CBK_ROUTE_BROKEN</b> : This callback is invoked when server 
indicates that the i3server corresponding to the next hop is dead, and some 
action is needed to recover.
+ *  </ol>
+ *
+ *  @param fun   The pointer to the function to be executed when the callback 
is invoked.
+ *  This function pointer should point to a function with following 
signature:<br>
+ *
+ *  <center><code>void funName (void *ctx_data, void *data, void 
*fun_ctx)</code></center>
+ *
+ *  The parameters to the callback function are used as follows:
+ *
+ *  <ul>
+ *
+ *      <li><b>ctx_data</b>: This is parameter is used to pass some context 
info when the callback is invoked.  For example, for a callback of type 
CL_CBK_TRIGGER_INSERTED, the pointer to the <code>cl_trigger</code> which was 
inserted is passed via this argument.  Please note that the function signature 
must assign the type <code>void *</code> to this argument.  The argument must 
be appropriately cast before use inside the function body.
+ *
+ *      <li><b>data</b>: This parameter is used to pass back some data which 
is generated at the time of callback invocation.
+ *      For example, in the callback of type CL_CBK_RECEIVE_PAYLOAD, the 
payload of the packet received is passed through this argument.
+ *
+ *      <li><b>fun_ctx</b>:  This parameter is used to pass back data which 
was stored at the time of callback registration.
+ *
+ *  </ul>
+ *
+ *  We now describe the values passed via the arguments of the callback 
function for the different callback types in the following table.
+ *
+ *  <table>
+ *      <tr>
+ *          <td>CALLBACK TYPE</td>
+ *          <td>ctx_data</td>
+ *          <td>data</td>
+ *          <td>fun_ctx</td>
+ *      </tr>
+ *
+ *      <tr>
+ *          <td>CL_CBK_TRIGGER_INSERTED</td>
+ *          <td><code>cl_trigger* t</code>, where t represents the inserted 
trigger</td>
+ *          <td><code>NULL</code>
+ *          <td>function context passed at callback registration</td>
+ *      </tr>
+ *
+ *      <tr>
+ *          <td>CL_CBK_TRIGGER_REFRESH_FAILED</td>
+ *          <td><code>cl_trigger* t</code>, where t represents the trigger 
whose refresh failed</td>
+ *          <td><code>NULL</code>
+ *          <td>function context passed at callback registration</td>
+ *      </tr>
+ *
+ *      <tr>
+ *          <td>CL_CBK_TRIGGER_NOT_FOUND</td>
+ *          <td><code>ID *id</code>, the id for which no matching trigger was 
found.</td>
+ *          <td><code>NULL</code></td>
+ *          <td>function context passed at callback registration</td>
+ *      </tr>
+ *
+ *      <tr>
+ *          <td>CL_CBK_RATELIMIT_EXCEEDED</td>
+ *          <td><code>ID *id</code>, the id whose token-bucket traffic 
constraints were violated.</td>
+ *          <td><code>NULL</code></td>
+ *          <td>function context passed at callback registration</td>
+ *      </tr>
+ *
+ *      <tr>
+ *          <td>CL_CBK_TRIGGER_CONSTRAINT_FAILED</td>
+ *          <td><code>ID *id</code>, the id for which trigger constraint 
failed.</td>
+ *          <td><code>NULL</code></td>
+ *          <td>function context passed at callback registration</td>
+ *      </tr>
+ *
+ *      <tr>
+ *          <td>CL_CBK_RECEIVE_PACKET</td>
+ *          <td><code>cl_trigger* t</code>, the trigger matching the packet's 
ID</td>
+ *          <td><code>cbk_packet* pkt</code> encapsulates the header and 
payload of the received packet.
+ *              Please note that the callback function should deallocate the 
memory pointed to by pkt after
+ *              it is no longer needed by using <code>free(pkt)</code>.  This 
frees up only the temporary encapsulating
+ *              cbk_packet and not the actual contents of the packet.</td>
+ *          <td>function context passed at callback registration</td>
+ *      </tr>
+ *
+ *      <tr>
+ *          <td>CL_CBK_RECEIVE_PAYLOAD</td>
+ *          <td><code>cl_trigger* t</code>, the trigger matching the packet's 
ID</td>
+ *          <td><code>cl_buf *b</code>, the payload of the data packet 
received</td>
+ *          <td>function context passed at callback registration</td>
+ *      </tr>
+ *
+ *      <tr>
+ *          <td>CL_CBK_SERVER_DOWN</td>
+ *          <td><code>struct in_addr *ip_addr</code>, the IP address of the 
server which is down</td>
+ *          <td><code>uint16_t *portNum</code>, the port on which i3 was 
supposed to have been running on the down server (TODO: It will better to 
aggregate the IP address and port info into a single structure as part of the 
first param.)</td>
+ *          <td>function context passed at callback registration</td>
+ *      </tr>
+ *
+ *      <tr>
+ *          <td>CL_CBK_ROUTE_BROKEN</td>
+ *          <td><code>cl_trigger *t</code>, the trigger whose route has been 
broken [[VERIFY: unclear]]</td>
+ *          <td><code>NULL</code></td>
+ *          <td>function context passed at callback registration</td>
+ *      </tr>
+ *  </table>
+ *
+ * @return One of the following codes is returned.
+ *      <ul>
+ *          <li><code>CL_RET_OK</code>
+ *
+ *          <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
+ *          invalid context. Probably cl_init() was not called initially.
+ *
+ *      </ul>
  */
-int cl_register_callback(
-            uint16_t cbk_type, 
-            void (*fun)(void *ctx_data, void *data, void *fun_ctx), 
-            void *fun_ctx) 
+int cl_register_callback(uint16_t cbk_type,
+                         void (*fun)(void *ctx_data, void *data, void 
*fun_ctx),
+                         void *fun_ctx)
 {
-  if (g_ctx == NULL)
-    return CL_RET_NO_CONTEXT;
+    if (g_ctx == NULL) {
+        return CL_RET_NO_CONTEXT;
+    }
 
-  return cl_ctx_register_callback(g_ctx, cbk_type, fun, fun_ctx);
+    return cl_ctx_register_callback(g_ctx, cbk_type, fun, fun_ctx);
 }
 
 /*
- * This function is used to register a callback associated with a 
- * particular trigger. These callbacks are similar to the callbacks 
+ * This function is used to register a callback associated with a
+ * particular trigger. These callbacks are similar to the callbacks
  * asssociated with the context (see cl_register_callback).
- * A callback associated with a trigger has strict priority over the same 
+ * A callback associated with a trigger has strict priority over the same
  * callback associated with the context.
  *
  * @param  t  The trigger with which the callback is associated.
  * @param cbk_type The callback type should be one of the following:
- *     <ol>
- *         <li><code>CL_CBK_TRIGGER_INSERTED<code>
- *         This callback is invoked when  the client receives the first ack
- *          as a result of a trigger insertion. 
+ *    <ol>
+ *        <li><code>CL_CBK_TRIGGER_INSERTED<code>
+ *        This callback is invoked when  the client receives the first ack
+ *          as a result of a trigger insertion.
  *
- *         <li><code>CL_CBK_TRIGGER_REFRESH_FAILED</code>
- *         This callback is invoked when the refreshing of a trigger fails. 
- *         A refreshing failure occurs when none of the client's refreshing 
messages
- *          is acked during a refresh period which has a duration of 
- *          <code>TRIGGER_REFRESH_PERIOD</code> sec. The client refreshes a 
trigger by 
- *         sending a refreshing message <code>MAX_NUM_TRIG_RETRIES * 
ACK_TIMEOUT</code> sec
- *         before the refreshing period expires. If the first refresh message 
is not
- *          acked, the client resends the refresh message approximately every 
+ *        <li><code>CL_CBK_TRIGGER_REFRESH_FAILED</code>
+ *        This callback is invoked when the refreshing of a trigger fails.
+ *        A refreshing failure occurs when none of the client's refreshing 
messages
+ *          is acked during a refresh period which has a duration of
+ *          <code>TRIGGER_REFRESH_PERIOD</code> sec. The client refreshes a 
trigger by
+ *        sending a refreshing message <code>MAX_NUM_TRIG_RETRIES * 
ACK_TIMEOUT</code> sec
+ *        before the refreshing period expires. If the first refresh message 
is not
+ *          acked, the client resends the refresh message approximately every
  *          <code>ACK_TIMEOUT</code> sec.
  *
  *          A typical response of the client to this callback is to reinsert 
the trigger
  *          using the cl_reinsert_trigger function.
- *                                  
- *         <li><code>CL_CBK_RECEIVE_PACKET</code>
- *         This callback is invoked upon receiving an i3 packet.
- *
- *                            The callback function has the following 
- *                            arguments: 
+ *
+ *        <li><code>CL_CBK_RECEIVE_PACKET</code>
+ *        This callback is invoked upon receiving an i3 packet.
+ *
+ *                            The callback function has the following
+ *                            arguments:
  *                                 fun(i3_trigger *t, i3_header *hdr,
- *                                     cl_buf *b, void *data), where "t" 
+ *                                     cl_buf *b, void *data), where "t"
  *                               represents the trigger matching the
- *                               the packet's ID, "hdr" represents the 
- *                               packet's header, "b" contains the 
+ *                               the packet's ID, "hdr" represents the
+ *                               packet's header, "b" contains the
  *                               packet's payload, and "data" represents
  *                               the client's data.
  *
- *         <li><code>CL_CBK_RECEIVE_PAYLOAD</code>
- *         This callback is invoked upon receiving a data packet. 
- *         This callback is suppressed by the 
<code>CL_CBK_RECEIVE_PACKET</code> callback.
+ *        <li><code>CL_CBK_RECEIVE_PAYLOAD</code>
+ *        This callback is invoked upon receiving a data packet.
+ *        This callback is suppressed by the 
<code>CL_CBK_RECEIVE_PACKET</code> callback.
  *
  *
  *   @param fun   The pointer to the function to be executed when the callback 
is invoked.
  *   This function pointer should point to a function with following 
signature:<br>
- *   
+ *
  *   <center><code>void funName (cl_trigger *ctr, void *data, void 
*fun_ctx)</code></center>
- *   
+ *
  *   The parameters to the callback function are used as follows:
- * 
+ *
  *   <ul>
- *   
+ *
  *       <li><b>ctr</b>: This parameter is used to pass a pointer to the 
trigger on which this
  *       callback was registered.
- *      
+ *
  *       <li><b>data</b>: This parameter is used to pass back some data which 
is generated
- *        at the time of callback invocation.  For example, in the callback of 
type 
- *        <code>CL_CBK_RECEIVE_PAYLOAD</code>, the payload of the packet 
received is passed 
+ *        at the time of callback invocation.  For example, in the callback of 
type
+ *        <code>CL_CBK_RECEIVE_PAYLOAD</code>, the payload of the packet 
received is passed
  *        via this argument.
  *
  *       <li><b>fun_ctx</b>:  This parameter is used to pass back data which 
was stored i
@@ -528,7 +523,7 @@
  *
  *  </ul>
  *
- *   We now describe the values passed via the arguments of the callback 
function for the 
+ *   We now describe the values passed via the arguments of the callback 
function for the
  *   different callback types in the following table.
  *
  *   <table>
@@ -538,21 +533,21 @@
  *           <td>data</td>
  *           <td>fun_ctx</td>
  *       </tr>
- *       
+ *
  *       <tr>
  *           <td>CL_CBK_TRIGGER_INSERTED</td>
  *           <td>ctr is a pointer to the inserted trigger</td>
  *           <td><code>NULL</code>
  *           <td>function context passed at callback registration</td>
  *       </tr>
- * 
+ *
  *       <tr>
  *           <td>CL_CBK_TRIGGER_REFRESH_FAILED</td>
  *           <td>ctr is a pointer to the trigger whose refresh failed</td>
  *           <td><code>NULL</code>
  *           <td>function context passed at callback registration</td>
  *       </tr>
- *   
+ *
  *       <tr>
  *           <td>CL_CBK_RECEIVE_PAYLOAD</td>
  *           <td>ctr is a pointer to the trigger matching the packet's ID</td>
@@ -561,71 +556,72 @@
  *       </tr>
  *   </table>
  * @return One of the following codes is returned.
- *     <ul>
- *         <li><code>CL_RET_OK</code> - 
- *         
- *         <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
- *         invalid context. Probably cl_init() was not called initially.
- *
- *         <li><code>CL_RET_NO_TRIGGER</code> - The trigger on which the 
callback
- *         is to be registered is NULL.
- *     </ul>
+ *    <ul>
+ *        <li><code>CL_RET_OK</code> -
+ *
+ *        <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was available or
+ *        invalid context. Probably cl_init() was not called initially.
+ *
+ *        <li><code>CL_RET_NO_TRIGGER</code> - The trigger on which the 
callback
+ *        is to be registered is NULL.
+ *    </ul>
  */
-int cl_register_trigger_callback(cl_trigger *ctr, uint16_t cbk_type, 
-                                void (*fun)(void*,void* data, void* fun_ctx), 
void *fun_ctx) //DILIP
+int cl_register_trigger_callback(cl_trigger *ctr, uint16_t cbk_type,
+                                 void (*fun)(void *, void *data, void 
*fun_ctx), void *fun_ctx) //DILIP
 {
-  if (g_ctx == NULL)
-    return CL_RET_NO_CONTEXT;
-  
-  if (!ctr) 
-    return CL_RET_NO_TRIGGER;
- 
-  return cl_register_trigger_callback1(ctr, cbk_type, fun, fun_ctx);
+    if (g_ctx == NULL) {
+        return CL_RET_NO_CONTEXT;
+    }
+
+    if (!ctr) {
+        return CL_RET_NO_TRIGGER;
+    }
+
+    return cl_register_trigger_callback1(ctr, cbk_type, fun, fun_ctx);
 }
 
 /*
- * This function is used to register a call back on a file descriptor open 
+ * This function is used to register a call back on a file descriptor open
  * for reading (e.g., a socket file descriptor).  The callback function is
  * executed whenever there is data available to be read on the file descriptor.
- * This callback does NOT read the data from fd on application's behalf; 
+ * This callback does NOT read the data from fd on application's behalf;
  * the application has to explicitly read data from fd.
  * The application is also responsible for opening and closing the associated 
file/socket.
  *
  * @param fd The file descriptor on which the callback is to be registered.
  * @param type The type of the file descriptor can be one of the following:
  *  <ul>
- *     <li><code>CL_FD_TYPE_READ</code>
- *     <li><code>CL_FD_TYPE_WRITE</code>
- *     <li><code>CL_FD_TYPE_EXCEPT</code>
+ *    <li><code>CL_FD_TYPE_READ</code>
+ *    <li><code>CL_FD_TYPE_WRITE</code>
+ *    <li><code>CL_FD_TYPE_EXCEPT</code>
  *  </ul>
  *
  * @param fun The function to be called back.  The function should have the
  * following signature:<br>
  * <center><code>void funName(int fd, void *data)</code></center>
  * I
- * @param data Application data to be passed when the callback is invoked 
+ * @param data Application data to be passed when the callback is invoked
  */
-int cl_register_fd_callback(int fd, int type, void (*fun)(int, void*), void 
*data)
+int cl_register_fd_callback(int fd, int type, void (*fun)(int, void *), void 
*data)
 {
-  return cl_ctx_register_fd_callback(g_ctx, fd, type, fun, data);
+    return cl_ctx_register_fd_callback(g_ctx, fd, type, fun, data);
 }
 
-
 /**
  * This function unregisters the callback associated with the specified file
  * descriptor.  This should be done once the file descriptor is closed.
  * @param fd The file descriptor whose callback is to be removed.
  * @param type The type of the file descriptor can be one of the following:
  *  <ul>
- *     <li><code>CL_FD_TYPE_READ</code>
- *     <li><code>CL_FD_TYPE_WRITE</code>
- *     <li><code>CL_FD_TYPE_EXCEPT</code>
+ *    <li><code>CL_FD_TYPE_READ</code>
+ *    <li><code>CL_FD_TYPE_WRITE</code>
+ *    <li><code>CL_FD_TYPE_EXCEPT</code>
  *  </ul>
  *
  */
 int cl_unregister_fd_callback(int fd, int type)
 {
-  return cl_ctx_unregister_fd_callback(g_ctx, fd, type);
+    return cl_ctx_unregister_fd_callback(g_ctx, fd, type);
 }
 
 /**
@@ -636,72 +632,72 @@
  * @param data Application data passed back to the application when the
  *           callback is invoked.
  *
- * @return A pointer to the created timer.  
+ * @return A pointer to the created timer.
  */
 cl_timer *cl_set_timer(struct timeval *tv, void (*fun)(void *), void *data)
 {
-  return cl_ctx_set_timer(g_ctx, tv, fun, data);
+    return cl_ctx_set_timer(g_ctx, tv, fun, data);
 }
 
-
-/** 
+/**
  * This function is used to cancel an existing timer.
  * @param ct The timer data structure of the timer to be cancelled.
  * This data structure is returned by <code>cl_set_timer</code>.
  */
 void cl_cancel_timer(cl_timer *ct)
 {
-  ct->cancel = TRUE;
+    ct->cancel = TRUE;
 }
 
 /*
- * This function is used to send a packet addressed to a stack 
+ * This function is used to send a packet addressed to a stack
  * of i3 ids.
- *  
+ *
  * @param stack The stack of i3 ids to which the packet is to be sent.
  * The stack is represented as an array of IDs; stack[0]
  * represents the ID where the packet is sent next
- * 
- * @param stack_len The number of IDs in the stack 
+ *
+ * @param stack_len The number of IDs in the stack
  * @param clb The packet payload
  * @param flags The flags associated with sending a packet. It can take on the
  * following values:
  *
  *  <ul>
- *     <li><code>CL_PKT_FLAG_ALLOW_SHORTCUT</code> All this packet to be 
shortcutted.  
+ *    <li><code>CL_PKT_FLAG_ALLOW_SHORTCUT</code> All this packet to be 
shortcutted.
  *  </ul>
  *
  *  @return One of the following codes is returned.
  *
- *     <ul>
- *         <li><code>CL_RET_OK</code> - Packet was successfully sent.
- *         <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was found.  
- *         Probably cl_init() was omitted initially.
- *         <li><code>CL_RET_INVALID_STACK_LEN</code> - The length of the stack 
is incorrect.
- *         <li><code>CL_RET_MSG_SIZE</code> - the packet payload is
- *         too large to be transferred.
- *         <li><code>CL_RET_NO_SERVERS</code> - no i3 servers are
- *         known or reachable.
- *         <li><code>CL_RET_NET_ERROR</code> - the packet was not
- *         sent due to a low-level network or socket error.
- *     </ul>
- */    
-int cl_send_stack(ID *stack, int stack_len, 
-                 cl_buf *clb, uint16_t flags)
+ *    <ul>
+ *        <li><code>CL_RET_OK</code> - Packet was successfully sent.
+ *        <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was found.
+ *        Probably cl_init() was omitted initially.
+ *        <li><code>CL_RET_INVALID_STACK_LEN</code> - The length of the stack 
is incorrect.
+ *        <li><code>CL_RET_MSG_SIZE</code> - the packet payload is
+ *        too large to be transferred.
+ *        <li><code>CL_RET_NO_SERVERS</code> - no i3 servers are
+ *        known or reachable.
+ *        <li><code>CL_RET_NET_ERROR</code> - the packet was not
+ *        sent due to a low-level network or socket error.
+ *    </ul>
+ */
+int cl_send_stack(ID *stack, int stack_len,
+                  cl_buf *clb, uint16_t flags)
 {
-  return cl_ctx_send_stack(g_ctx, stack, stack_len, clb, flags);
+    return cl_ctx_send_stack(g_ctx, stack, stack_len, clb, flags);
 }
+
 /************************************************************************
  * Returns RTT of given addr (in host format)
  ***********************************************************************/
 int cl_get_rtt_server(uint32_t addr, uint64_t *rtt)
 {
-    return cl_ctx_get_rtt_server (g_ctx, addr, rtt);
+    return cl_ctx_get_rtt_server(g_ctx, addr, rtt);
 }
 
 int cl_get_rtt_id(ID *id, uint64_t *rtt)
-{ 
-    return cl_ctx_get_rtt_id (g_ctx, id, rtt);
+{
+    return cl_ctx_get_rtt_id(g_ctx, id, rtt);
 }
 
 /************************************************************************
@@ -711,13 +707,12 @@
  * returned (may be smaller than requested)
  ***********************************************************************/
 int cl_get_top_k_servers(int *k, uint32_t best_addr[],
-               uint16_t best_port[], uint64_t  best_rtt[])
-{ 
+                         uint16_t best_port[], uint64_t best_rtt[])
+{
     return cl_ctx_get_top_k_servers(g_ctx, k, best_addr, best_port, best_rtt);
 }
 
 int cl_get_top_k_ids(int *k, ID best_id[], uint64_t best_rtt[])
 {
-    return cl_ctx_get_top_k_ids (g_ctx, k, best_id, best_rtt);
+    return cl_ctx_get_top_k_ids(g_ctx, k, best_id, best_rtt);
 }
-

=== modified file 'i3/i3_client/i3_client_api.h'
--- i3/i3_client/i3_client_api.h        2010-01-12 12:35:31 +0000
+++ i3/i3_client/i3_client_api.h        2010-02-11 11:49:47 +0000
@@ -1,9 +1,9 @@
 /***************************************************************************
-                          i3_client_api.h  -  description
-                             -------------------
-    begin                : Aug 20 2003
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
+*                         i3_client_api.h  -  description
+*                            -------------------
+*   begin                : Aug 20 2003
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
 
 #ifndef I3_CLIENT_API_H
 #define I3_CLIENT_API_H
@@ -13,52 +13,52 @@
 
 #define cl_timer Event
 
-/** 
-  * cbk_packet stands for "Callback Packet".
-  * This structure encapsulates the contents
-  * of a packet and the stack of IDs and stack len associated with 
-  * its header.  It is used in the data arguments of callbacks of type
-  * CL_CBK_RECEIVE_PACKET.
-  */
+/**
+ * cbk_packet stands for "Callback Packet".
+ * This structure encapsulates the contents
+ * of a packet and the stack of IDs and stack len associated with
+ * its header.  It is used in the data arguments of callbacks of type
+ * CL_CBK_RECEIVE_PACKET.
+ */
 typedef struct cbk_packet {
-  ID *ids;      /** Stack of IDs associated with the packet. */
-  int stack_len;      /** Number of IDs in the stack */
-  cl_buf* clb;  /** The contents of the packet */
+    ID *    ids; /** Stack of IDs associated with the packet. */
+    int     stack_len; /** Number of IDs in the stack */
+    cl_buf *clb; /** The contents of the packet */
 } cbk_packet;
 
 
 int cl_init(char *cfg_file);
 int cl_exit(void);
 
-int cl_select(int n, fd_set *readfds, fd_set *writefds, 
-             fd_set *exceptfds, struct timeval *cl_to);
+int cl_select(int n, fd_set *readfds, fd_set *writefds,
+              fd_set *exceptfds, struct timeval *cl_to);
 int cl_loop(void);
 
 
-cl_trigger *cl_create_trigger(ID *id, uint16_t prefix_len, Key *key, 
-                             uint16_t flags);
+cl_trigger *cl_create_trigger(ID *id, uint16_t prefix_len, Key *key,
+                              uint16_t flags);
 
-cl_trigger *cl_create_trigger_stack(ID *id, uint16_t prefix_len, 
-                                   ID *stack, int stack_len, 
-                                   uint16_t flags);
+cl_trigger *cl_create_trigger_stack(ID *id, uint16_t prefix_len,
+                                    ID *stack, int stack_len,
+                                    uint16_t flags);
 
 /**
  * This function is used to create a trigger which points to an i3 id.
  * Please note that this function does not insert the trigger into the i3 
infrastructure.
  * <code>cl_insert_trigger</code> is used to insert the trigger into the i3 
infrastructure.
- * 
+ *
  * @param id The i3 Id of the trigger to be created.
- * 
+ *
  * @param prefix_len The length of the prefix of the id to be used for 
matching.
- * 
+ *
  * @param id_target The i3 Id to which this trigger points.
  *
  * @param flags Flags are used to specify the properties of the trigger being 
created.
  * The following flags can be used individually or ORed together.
  * <ul>
- *     <li><code>CL_TRIGGER_CFLAG_R_CONSTRAINT</code> - Make the trigger right 
constrained.
+ *    <li><code>CL_TRIGGER_CFLAG_R_CONSTRAINT</code> - Make the trigger right 
constrained.
  *      <li><code>CL_TRIGGER_CFLAG_L_CONSTRAINT</code> - Make the trigger left 
constrained.
- *      <li><code>CL_TRIGGER_CFLAG_PUBLIC</code> - Make this a public trigger. 
 If this is flag is 
+ *      <li><code>CL_TRIGGER_CFLAG_PUBLIC</code> - Make this a public trigger. 
 If this is flag is
  *      not used, the trigger is private by default.  Please note that a 
public trigger must be left constrained.
  *      This means that you cannot use the flags 
<code>CL_TRIGGER_CFLAG_R_CONSTRAINT</code> and
  *      CL_TRIGGER_CFLAG_PUBLIC together.
@@ -67,7 +67,7 @@
  * @return A pointer to the created trigger.
  */
 #define cl_create_trigger_id(id, prefix_len, id_target, flags) \
-  cl_create_trigger_stack(id, prefix_len, id_target, 1, flags)
+    cl_create_trigger_stack(id, prefix_len, id_target, 1, flags)
 
 int cl_destroy_trigger(cl_trigger *ctr);
 
@@ -80,48 +80,48 @@
 
 /*
  * This function is used to send a packet addressed to an i3 Id.
- *  
- * @param id The i3 id to which this packet is addressed 
+ *
+ * @param id The i3 id to which this packet is addressed
  * @param clb The packet payload
  * @param flags The flags associated with sending a packet. It can take on the
  * following values:
  *
  *  <ul>
- *     <li><code>CL_PKT_FLAG_ALLOW_SHORTCUT</code> All this packet to be 
shortcutted.  
+ *    <li><code>CL_PKT_FLAG_ALLOW_SHORTCUT</code> All this packet to be 
shortcutted.
  *  </ul>
  *
  *  @return One of the following codes is returned.
  *
- *     <ul>
- *         <li><code>CL_RET_OK</code> - Packet was successfully sent.
- *         <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was found.  
- *         Probably cl_init() was omitted initially.
- *         <li><code>CL_RET_MSG_SIZE</code> - the packet payload is
- *         too large to be transferred.
- *         <li><code>CL_RET_NO_SERVERS</code> - no i3 servers are
- *         known or reachable.
- *         <li><code>CL_RET_NET_ERROR</code> - the packet was not
- *         sent due to a low-level network or socket error.
- *     </ul>
- */    
+ *    <ul>
+ *        <li><code>CL_RET_OK</code> - Packet was successfully sent.
+ *        <li><code>CL_RET_NO_CONTEXT</code> - No i3 context was found.
+ *        Probably cl_init() was omitted initially.
+ *        <li><code>CL_RET_MSG_SIZE</code> - the packet payload is
+ *        too large to be transferred.
+ *        <li><code>CL_RET_NO_SERVERS</code> - no i3 servers are
+ *        known or reachable.
+ *        <li><code>CL_RET_NET_ERROR</code> - the packet was not
+ *        sent due to a low-level network or socket error.
+ *    </ul>
+ */
 #define cl_send(id, clb, flags) cl_send_stack(id, 1, clb, flags)
 
 
-int cl_register_trigger_callback(cl_trigger *ctr, uint16_t cbk_type, 
-                                void (*fun)(void*, void* data, void* fun_ctx), 
void *fun_ctx);
+int cl_register_trigger_callback(cl_trigger * ctr, uint16_t cbk_type,
+                                 void (*fun)(void *, void *data, void 
*fun_ctx), void *fun_ctx);
 
 int cl_register_callback(
-            uint16_t cbk_type, 
-            void (*fun)(void *ctx_data, void *data, void *fun_ctx), 
-            void *fun_ctx);
+    uint16_t cbk_type,
+    void (*fun)(void *ctx_data, void *data, void *fun_ctx),
+    void *fun_ctx);
 
-int cl_register_fd_callback(int fd, int type, void (*fun)(int, void*), void 
*data);
+int cl_register_fd_callback(int fd, int type, void (*fun)(int, void *), void 
*data);
 int cl_unregister_fd_callback(int fd, int type);
 
 cl_timer *cl_set_timer(struct timeval *tv, void (*fun)(void *), void *data);
 void cl_cancel_timer(cl_timer *ct);
 
-/* 
+/*
  * Create a cl_bug data structure which is used for sending and receiving 
packets.
  * @param len The size of the buffer to be created.
  */
@@ -133,8 +133,8 @@
  */
 void cl_free_buf(cl_buf *clb);
 
-/* 
- * Get close servers from a list of servers 
+/*
+ * Get close servers from a list of servers
  *   - currently uses a combination of latitude-longitude + pings
  */
 int cl_get_rtt_server(uint32_t addr, uint64_t *rtt);

=== modified file 'i3/i3_client/i3_client_api_ctx.c'
--- i3/i3_client/i3_client_api_ctx.c    2010-01-12 12:35:31 +0000
+++ i3/i3_client/i3_client_api_ctx.c    2010-02-11 11:49:47 +0000
@@ -1,6 +1,6 @@
 /************************************************************************
- * cl_ctx_init - create and initialize a context data structure 
- * 
+ * cl_ctx_init - create and initialize a context data structure
+ *
  *  input:
  *    cfg_file - xml file containing configuration parameters
  *               such as the servers to which the client can connect
@@ -9,7 +9,7 @@
  *               CL_RET_INVALID_CFG_FILE
  *               CL_RE_NO_CONTEXT
  *               error code returned cl_init_ping
- *               
+ *
  *  return value:
  *   ctx - pointer to the context
  *
@@ -21,7 +21,7 @@
 #include <string.h> // strcasecmp()
 #include <stdlib.h> // exit()
 #ifdef _WIN32
-    // stg: win does not have strcasecmp():
+// stg: win does not have strcasecmp():
     #define strcasecmp _stricmp
 #endif
 
@@ -42,267 +42,268 @@
 
 
 
-int cl_init_ping(cl_context* ctx, char *url);
+int cl_init_ping(cl_context *ctx, char *url);
 void trigger_set_timer(struct timeval *tv, void (*fun)(void *), cl_trigger 
*ctr);
 
 
 /**
-  * @param i3_port_num The port on which i3 should listen.
-  */
+ * @param i3_port_num The port on which i3 should listen.
+ */
 cl_context *cl_ctx_init(const char *cfg_file, int *rc, int i3_port_num)
 {
-  char usePingStr[50];
-  char useTCPStr[50];
-  
-  cl_context *ctx;
-
-  // Open the debug file to which all debug and info messages related to i3 
are sent,
-  // if it had not be previously opened.  
-  // For eg: if the i3 client api is used as part of the i3OCD, the i3OCD
-  // sets up i3DebugFD as soon as the i3OCD dll is loaded.
+    char usePingStr[50];
+    char useTCPStr[50];
+
+    cl_context *ctx;
+
+    // Open the debug file to which all debug and info messages related to i3 
are sent,
+    // if it had not be previously opened.
+    // For eg: if the i3 client api is used as part of the i3OCD, the i3OCD
+    // sets up i3DebugFD as soon as the i3OCD dll is loaded.
 #ifdef _WIN32
-  if (i3DebugFD == NULL) {
-       i3DebugFD = fopen ("debug_i3.txt", "w");
-  }
+    if (i3DebugFD == NULL) {
+        i3DebugFD = fopen("debug_i3.txt", "w");
+    }
 #endif
-  if (0 != nw_init()) {
-         I3_PRINT_INFO0 (I3_INFO_LEVEL_FATAL_ERROR, "Unable to initialize the 
network.\n");
-         EXIT_ON_ERROR;
-      return NULL;
-  }
-
-  if (!cfg_file) {
-    *rc = CL_RET_INVALID_CFG_FILE;
-    return NULL;
-  }
-
-  /* read configuration file */
-  read_parameters(cfg_file);
-
-  /* create context */
-  ctx = cl_create_context(NULL, i3_port_num);
-  if (ctx)
-    *rc = CL_RET_OK;
-  else {
-    *rc = CL_RET_NO_CONTEXT;
+    if (0 != nw_init()) {
+        I3_PRINT_INFO0(I3_INFO_LEVEL_FATAL_ERROR, "Unable to initialize the 
network.\n");
+        EXIT_ON_ERROR;
+        return NULL;
+    }
+
+    if (!cfg_file) {
+        *rc = CL_RET_INVALID_CFG_FILE;
+        return NULL;
+    }
+
+    /* read configuration file */
+    read_parameters(cfg_file);
+
+    /* create context */
+    ctx = cl_create_context(NULL, i3_port_num);
+    if (ctx) {
+        *rc = CL_RET_OK;
+    } else {
+        *rc = CL_RET_NO_CONTEXT;
+        return ctx;
+    }
+
+    /* Should TCP be used to find the first hop i3 server? */
+    read_string_attribute("//I3ServerDetails", "UseTCP", useTCPStr, 0);
+    if (strcasecmp(useTCPStr, "yes") == 0 || strcasecmp(useTCPStr, "true") == 
0) {
+        ctx->is_tcp = 1;
+    } else {
+        ctx->is_tcp = 0;
+    }
+
+    /* check whether ping is used to find a nearby server */
+    read_string_attribute("//I3ServerDetails", "UsePing", usePingStr, 0);
+    if (strcasecmp(usePingStr, "yes") == 0 || strcasecmp(usePingStr, "true") 
== 0) {
+        ctx->use_ping = 1;
+    } else {
+        ctx->use_ping = 0;
+    }
+
+    if (ctx->use_ping) {
+#define STATUS_URL_LEN 1024
+        char status_url[STATUS_URL_LEN];
+
+        /* read the url containing the list of i3 serevers */
+        read_string_attribute("//I3ServerDetails", "ServerListURL", 
status_url, 0);
+
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_SUPER, "Using ping, server status url = 
%s\n\n", status_url);
+
+        if (strlen(status_url) >= STATUS_URL_LEN) {
+            I3_PRINT_INFO1(I3_INFO_LEVEL_WARNING, "cl_ctx_init: status_url 
file too long in %s\n", cfg_file);
+            exit(-1);
+        }
+        if (strlen(status_url) == 0) {
+            I3_PRINT_INFO1(I3_INFO_LEVEL_WARNING, "cl_ctx_init: no status_url 
file in %s\n", cfg_file);
+            exit(-1);
+        }
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_VERBOSE, "Starting ping thread\n");
+        *rc = cl_init_ping(ctx, status_url);
+    }
+
+    // Don't read the configuration file after this point.
+    release_params();
+
+    if (ctx->num_servers < 1 && !ctx->use_ping) {
+        I3_PRINT_INFO0(
+            I3_INFO_LEVEL_FATAL_ERROR,
+            "No i3 server details have been given and UsePing is turned off.\n"
+            "There is no way to obtain i3 server details. Exiting.\n"
+            );
+        EXIT_ON_ERROR;
+    }
+
+    // This function intializes the TCP socket to be used to contact the first 
hop i3 server,
+    // if UseTCP flag is set in the configuration file.
+    // If UsePing is set, this function blocks till the details of at least
+    // one i3 server is available.
+    init_tcp_ctx(ctx);
+
     return ctx;
-  }
-  
-  /* Should TCP be used to find the first hop i3 server? */
-  read_string_attribute("//I3ServerDetails", "UseTCP", useTCPStr,0);
-  if (strcasecmp(useTCPStr, "yes") == 0 || strcasecmp(useTCPStr, "true") == 0) 
{
-     ctx->is_tcp = 1;
-  } else {
-     ctx->is_tcp = 0;
-  }
-   
-  /* check whether ping is used to find a nearby server */
-  read_string_attribute("//I3ServerDetails", "UsePing", usePingStr,0);
-  if (strcasecmp(usePingStr, "yes") == 0 || strcasecmp(usePingStr, "true") == 
0) {
-     ctx->use_ping = 1;
-  } else {
-     ctx->use_ping = 0;
-  }
-
-  if (ctx->use_ping) {
-#define STATUS_URL_LEN 1024
-    char status_url[STATUS_URL_LEN];
-
-    /* read the url containing the list of i3 serevers */
-    read_string_attribute("//I3ServerDetails", "ServerListURL", status_url, 0);
-
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_SUPER, "Using ping, server status url = 
%s\n\n", status_url);
-
-    if (strlen(status_url) >= STATUS_URL_LEN) {
-      I3_PRINT_INFO1(I3_INFO_LEVEL_WARNING, "cl_ctx_init: status_url file too 
long in %s\n", cfg_file);
-      exit(-1);
-    }
-    if (strlen(status_url) == 0) {
-      I3_PRINT_INFO1(I3_INFO_LEVEL_WARNING, "cl_ctx_init: no status_url file 
in %s\n", cfg_file);
-      exit(-1);
-    }
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_VERBOSE, "Starting ping thread\n");
-    *rc = cl_init_ping(ctx, status_url);
-  }
- 
-  // Don't read the configuration file after this point.
-  release_params();
-  
-  if (ctx->num_servers < 1 && ! ctx->use_ping) {
-      I3_PRINT_INFO0 (
-              I3_INFO_LEVEL_FATAL_ERROR,
-              "No i3 server details have been given and UsePing is turned 
off.\n"
-              "There is no way to obtain i3 server details. Exiting.\n"
-              );
-      EXIT_ON_ERROR;
-  }
-              
-  // This function intializes the TCP socket to be used to contact the first 
hop i3 server,
-  // if UseTCP flag is set in the configuration file.
-  // If UsePing is set, this function blocks till the details of at least
-  // one i3 server is available.
-  init_tcp_ctx(ctx);
-
-  return ctx;
 }
 
-
 /************************************************************************
  * cl_ctx_exit - free all resources associated with the context (ctx)
  ***********************************************************************/
 int cl_ctx_exit(cl_context *ctx)
 {
-  if (ctx == NULL)
-    return CL_RET_NO_CONTEXT;
-   
-  cl_destroy_context(ctx);
-
-  return CL_RET_OK;
+    if (ctx == NULL) {
+        return CL_RET_NO_CONTEXT;
+    }
+
+    cl_destroy_context(ctx);
+
+    return CL_RET_OK;
 }
- 
-
 
 int cl_ctx_loop(cl_context *ctx)
 {
     fd_set rset;
 
     if (ctx == NULL) {
-        return CL_RET_NO_CONTEXT; 
+        return CL_RET_NO_CONTEXT;
     }
-  
+
     FD_ZERO(&rset);
 
-    for (;;) {
+    for (;; ) {
 #ifndef _WIN32
-       FD_SET(0, &rset); /* just here, to be modified if application
-                               * listens on other fds
-                               */
+        FD_SET(0, &rset); /* just here, to be modified if application
+                           * listens on other fds
+                           */
 #endif
         if (cl_select(0, &rset, NULL, NULL, NULL) < 0) {
             if (errno == EINTR) {
-                   continue;
+                continue;
             } else {
-                   I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_FATAL, "select_error\n");
+                I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_FATAL, "select_error\n");
             }
         }
     }
-  return errno;
+    return errno;
 }
 
 /*************************************************************************
- * cl_ctx_create_trigger - create a trigger that points to the client, 
- *                         i.e., to the context's socket
- * 
- * input:
- *   ctx - context (only for cl_ctx_create_trigger)
- *   id, prefix_len  - trigger ID and prefix len
- *   key - key = h_l(id) if the trigger is left constrained, and
- *               h_r(id) if the trigger is right constrained, where h_l
- *               and h_r are two one-way hash functions
- *   flags - flags associated to trigger creation; possible values:
- *           CL_TRIGGER_CFLAG_R_CONSTRAINT - right constraint trigger
- *           CL_TRIGGER_CFLAG_L_CONSTRAINT - left constraint trigger
- *           CL_TRIGGER_CFLAG_PUBLIC - public trigger; otherwise the trigger
- *                                     is private. If the trigger is public
- *                                     then it has to be left constraint, 
- *                                     i.e., CL_TRIGGER_CFLAG_R_CONSTRAINT 
- *                                     and CL_TRIGGER_CFLAG_PUBLIC cannot be
- *                                     used simultaneously
- *   rc -  error code; possible values:
- *           CL_RET_NO_CONTEXT
- *           CL_RET_TRIGGER_ALREADY_EXISTS
- *           error code returned by update_id_key
- *   
- * return value:
- *   - pointer to the instantiated trigger
- *
- * Note:
- *   - the key field of the ID is upadted to h_l(key) or h_r(key)     
- *************************************************************************/
+* cl_ctx_create_trigger - create a trigger that points to the client,
+*                         i.e., to the context's socket
+*
+* input:
+*   ctx - context (only for cl_ctx_create_trigger)
+*   id, prefix_len  - trigger ID and prefix len
+*   key - key = h_l(id) if the trigger is left constrained, and
+*               h_r(id) if the trigger is right constrained, where h_l
+*               and h_r are two one-way hash functions
+*   flags - flags associated to trigger creation; possible values:
+*           CL_TRIGGER_CFLAG_R_CONSTRAINT - right constraint trigger
+*           CL_TRIGGER_CFLAG_L_CONSTRAINT - left constraint trigger
+*           CL_TRIGGER_CFLAG_PUBLIC - public trigger; otherwise the trigger
+*                                     is private. If the trigger is public
+*                                     then it has to be left constraint,
+*                                     i.e., CL_TRIGGER_CFLAG_R_CONSTRAINT
+*                                     and CL_TRIGGER_CFLAG_PUBLIC cannot be
+*                                     used simultaneously
+*   rc -  error code; possible values:
+*           CL_RET_NO_CONTEXT
+*           CL_RET_TRIGGER_ALREADY_EXISTS
+*           error code returned by update_id_key
+*
+* return value:
+*   - pointer to the instantiated trigger
+*
+* Note:
+*   - the key field of the ID is upadted to h_l(key) or h_r(key)
+*************************************************************************/
 cl_trigger *cl_ctx_create_trigger(cl_context *ctx,
-                                 ID *id, uint16_t prefix_len, Key *key, 
-                                 uint16_t flags, int *rc)
+                                  ID *id, uint16_t prefix_len, Key *key,
+                                  uint16_t flags, int *rc)
 {
-  cl_trigger *ctr;
-
-  //ADDED_DILIP
-  *rc = CL_RET_OK; //default return code if nothing goes wrong
- 
-  if (!ctx) {
-    *rc = CL_RET_NO_CONTEXT;
-    return NULL;
-  }
- 
-  *rc = update_id_key(id, key, flags);
-  if (*rc != CL_RET_OK)
-    return NULL;
-
-  ctr = cl_create_trigger_gen(ctx,
-                             I3_ADDR_TYPE_IPv4, id, prefix_len, 
-                             ctx->local_ip_addr, ctx->local_port, 
-                             NULL, key,
-                             /* flags are initialized in 
-                              * cl_ctx_insert_trigger
-                              */
-                             0);
-  if (!ctr) {
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_ctx_create_trigger: duplicate 
trigger insertion.\n");
-    ctr = cl_get_trigger_by_id(ctx->trigger_htable[CL_HASH_TRIG(id)], id);
-    if (ctr)
-      *rc = CL_RET_TRIGGER_ALREADY_EXISTS;
-  }
-
-  return ctr;
+    cl_trigger *ctr;
+
+    //ADDED_DILIP
+    *rc = CL_RET_OK; //default return code if nothing goes wrong
+
+    if (!ctx) {
+        *rc = CL_RET_NO_CONTEXT;
+        return NULL;
+    }
+
+    *rc = update_id_key(id, key, flags);
+    if (*rc != CL_RET_OK) {
+        return NULL;
+    }
+
+    ctr = cl_create_trigger_gen(ctx,
+                                I3_ADDR_TYPE_IPv4, id, prefix_len,
+                                ctx->local_ip_addr, ctx->local_port,
+                                NULL, key,
+                                /* flags are initialized in
+                                 * cl_ctx_insert_trigger
+                                 */
+                                0);
+    if (!ctr) {
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_ctx_create_trigger: 
duplicate trigger insertion.\n");
+        ctr = cl_get_trigger_by_id(ctx->trigger_htable[CL_HASH_TRIG(id)], id);
+        if (ctr) {
+            *rc = CL_RET_TRIGGER_ALREADY_EXISTS;
+        }
+    }
+
+    return ctr;
 }
- 
 
 /*************************************************************************
- * cl_ctx_create_trigger_stack - same as
- *   cl_ctx_create_trigger/cl_create_trigger_addr but the trigger
- *   points to stack instead of the contex's socket
- *************************************************************************/
+* cl_ctx_create_trigger_stack - same as
+*   cl_ctx_create_trigger/cl_create_trigger_addr but the trigger
+*   points to stack instead of the contex's socket
+*************************************************************************/
 cl_trigger *cl_ctx_create_trigger_stack(cl_context *ctx,
-                                       ID *id, uint16_t prefix_len, 
-                                       ID *stack, int stack_len, 
-                                       uint16_t flags, int *rc)
+                                        ID *id, uint16_t prefix_len,
+                                        ID *stack, int stack_len,
+                                        uint16_t flags, int *rc)
 {
-  cl_trigger *ctr;
-  i3_stack   *s;
-
-  struct in_addr nothing;
-  nothing.s_addr = 0; // this line not necessary, but just here to avoid the 
warning.
-
-  if (!ctx) {
-    *rc = CL_RET_NO_CONTEXT;
-    return NULL;
-  }
-  
-  if (stack_len == 0 || stack_len >= I3_MAX_STACK_LEN) {
-    *rc = CL_RET_INVALID_STACK_LEN;
-    return NULL;
-  }
-
-  *rc = update_id_id(id, &stack[0], flags);
-
-  if (*rc != CL_RET_OK)
-    return NULL;
-
-  s = alloc_i3_stack();
-  init_i3_stack(s, stack, stack_len);
-
-  ctr = cl_create_trigger_gen(ctx, I3_ADDR_TYPE_STACK, 
-                             id, prefix_len, nothing, 0, s, 0, 0);
-
-  if (!ctr) {
-    free_i3_stack(s);
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, 
-               "cl_ctx_create_trigger_stack: duplicate trigger insertion.\n");
-    ctr = cl_get_trigger_by_id(ctx->trigger_htable[CL_HASH_TRIG(id)], id);
-    if (ctr)
-      *rc = CL_RET_TRIGGER_ALREADY_EXISTS;
-  }
-
-  return ctr;
+    cl_trigger *ctr;
+    i3_stack *s;
+
+    struct in_addr nothing;
+    nothing.s_addr = 0; // this line not necessary, but just here to avoid the 
warning.
+
+    if (!ctx) {
+        *rc = CL_RET_NO_CONTEXT;
+        return NULL;
+    }
+
+    if (stack_len == 0 || stack_len >= I3_MAX_STACK_LEN) {
+        *rc = CL_RET_INVALID_STACK_LEN;
+        return NULL;
+    }
+
+    *rc = update_id_id(id, &stack[0], flags);
+
+    if (*rc != CL_RET_OK) {
+        return NULL;
+    }
+
+    s   = alloc_i3_stack();
+    init_i3_stack(s, stack, stack_len);
+
+    ctr = cl_create_trigger_gen(ctx, I3_ADDR_TYPE_STACK,
+                                id, prefix_len, nothing, 0, s, 0, 0);
+
+    if (!ctr) {
+        free_i3_stack(s);
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL,
+                        "cl_ctx_create_trigger_stack: duplicate trigger 
insertion.\n");
+        ctr = cl_get_trigger_by_id(ctx->trigger_htable[CL_HASH_TRIG(id)], id);
+        if (ctr) {
+            *rc = CL_RET_TRIGGER_ALREADY_EXISTS;
+        }
+    }
+
+    return ctr;
 }
 
 /********************************************************************
@@ -311,218 +312,236 @@
  * input:
  *   ctx - context (only for cl_ctx_destroy_trigger)
  *   ctr - trigger to be destroyed
- *     
+ *
  * return value:
- *   - error code; possibe values 
+ *   - error code; possibe values
  *       CL_RET_OK
  *       CL_RET_NO_TRIGGER
- *       CL_RET_NO_CONTEXT 
- *        
+ *       CL_RET_NO_CONTEXT
+ *
  * Note: if the trigger is not removed from the infrastructure, this
  *       function removes it
  *******************************************************************/
 int cl_ctx_destroy_trigger(cl_context *ctx, cl_trigger *ctr)
 {
-  int rc;
-
-  if (!ctx) 
-    return CL_RET_NO_CONTEXT;
-  
-  if (!ctr) 
-    return CL_RET_NO_TRIGGER;
-   
-  if (ctr->type == CL_TRIGGER_I3) {
-    rc = cl_ctx_remove_trigger(ctx, ctr);
-    if (rc != CL_RET_OK)
-      return rc;
-  }
-
-  cl_delete_trigger(ctx, ctr);
-
-  return CL_RET_OK;
+    int rc;
+
+    if (!ctx) {
+        return CL_RET_NO_CONTEXT;
+    }
+
+    if (!ctr) {
+        return CL_RET_NO_TRIGGER;
+    }
+
+    if (ctr->type == CL_TRIGGER_I3) {
+        rc = cl_ctx_remove_trigger(ctx, ctr);
+        if (rc != CL_RET_OK) {
+            return rc;
+        }
+    }
+
+    cl_delete_trigger(ctx, ctr);
+
+    return CL_RET_OK;
 }
 
 /************************************************************************
- * cl_ctx_insert_trigger - insert a trigger into i3 
- *
- * input: 
- *   ctx - context (only for cl_ctx_insert_trigger)
- *   ctr - trigger
- *   flags - flags associated to trigger insertion; possible values
- *      
- ************************************************************************/
-int cl_ctx_insert_trigger(cl_context *ctx, cl_trigger *ctr, uint16_t flags) 
-{
-  struct timeval tv;
-
-  if (!ctr)
-    return CL_RET_NO_TRIGGER;
-
-  if (!ctx)
-    return CL_RET_NO_CONTEXT;
-
-  if (flags & CL_IFLAGS_TRIGGER_LOCAL) 
-    ctr->type = CL_TRIGGER_LOCAL;
-  else 
-    ctr->type = CL_TRIGGER_I3;
-
-  if (flags & CL_IFLAGS_TRIGGER_ALLOW_SHORTCUT)
-    ctr->t->flags |= I3_TRIGGER_FLAG_ALLOW_SHORTCUT;
-
-  if (ctr->type == CL_TRIGGER_I3) {
-    cl_insert_trigger_into_i3(ctx, ctr);
+* cl_ctx_insert_trigger - insert a trigger into i3
+*
+* input:
+*   ctx - context (only for cl_ctx_insert_trigger)
+*   ctr - trigger
+*   flags - flags associated to trigger insertion; possible values
+*
+************************************************************************/
+int cl_ctx_insert_trigger(cl_context *ctx, cl_trigger *ctr, uint16_t flags)
+{
+    struct timeval tv;
+
+    if (!ctr) {
+        return CL_RET_NO_TRIGGER;
+    }
+
+    if (!ctx) {
+        return CL_RET_NO_CONTEXT;
+    }
+
+    if (flags & CL_IFLAGS_TRIGGER_LOCAL) {
+        ctr->type = CL_TRIGGER_LOCAL;
+    } else {
+        ctr->type = CL_TRIGGER_I3;
+    }
+
+    if (flags & CL_IFLAGS_TRIGGER_ALLOW_SHORTCUT) {
+        ctr->t->flags |= I3_TRIGGER_FLAG_ALLOW_SHORTCUT;
+    }
+
+    if (ctr->type == CL_TRIGGER_I3) {
+        cl_insert_trigger_into_i3(ctx, ctr);
+        if (ctr->status == CL_TRIGGER_STATUS_INSERTED) {
+            /* trigger already inserted; just update trigger info;
+             * no need to set-up timeout_ack_timer
+             */
+            ;
+        } else {
+            /* set challenge timeout  */
+            tv.tv_sec  = ACK_TIMEOUT;
+            tv.tv_usec = random_sec();
+            trigger_set_timer(&tv, timeout_ack_insert, ctr);
+        }
+    } else {
+        /* do nothing */;
+    }
+
+    //ADDED_DILIP
+    return CL_RET_OK;
+}
+
+int cl_ctx_trigger_ratelimit(cl_context *ctx, cl_trigger *ctr, uint8_t type,
+                             uint32_t depth, uint32_t r, uint32_t R)
+{
+    if (ctx == NULL) {
+        return CL_RET_NO_CONTEXT;
+    }
+
+    if (!ctr) {
+        return CL_RET_NO_TRIGGER;
+    }
+
+    if (ctr->t->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
+        assert(ctr->t->tb);
+        /* trigger is already rate limited; just update the token buket */
+        ctr->t->tb->type  = type;
+        ctr->t->tb->depth = depth;
+        ctr->t->tb->r     = r;
+        ctr->t->tb->R     = R;
+        if (ctr->precomputed_pkt.p) {
+            free(ctr->precomputed_pkt.p);
+            /* need to precompute the packet after the change */
+            cl_make_trigger_packet(ctx, ctr->t,
+                                   I3_OPT_TRIGGER_INSERT, 
&ctr->precomputed_pkt);
+        }
+    } else {
+        ctr->t->flags |= I3_TRIGGER_FLAG_RATE_LIMIT;
+        ctr->t->tb     = alloc_token_bucket();
+        init_token_bucket(ctr->t->tb, type, depth, r, R);
+    }
     if (ctr->status == CL_TRIGGER_STATUS_INSERTED) {
-      /* trigger already inserted; just update trigger info;
-       * no need to set-up timeout_ack_timer 
-       */
-      ;
-    } else {
-      /* set challenge timeout  */
-      tv.tv_sec  = ACK_TIMEOUT;
-      tv.tv_usec = random_sec();
-      trigger_set_timer(&tv, timeout_ack_insert, ctr);
-    }
-  } else {
-    /* do nothing */ ;
-  }
-  
-  //ADDED_DILIP
-  return CL_RET_OK;
-
-}
-
-
-int cl_ctx_trigger_ratelimit(cl_context* ctx, cl_trigger *ctr, uint8_t type,
-                            uint32_t depth, uint32_t r, uint32_t R)
-{
-  if (ctx == NULL)
-    return CL_RET_NO_CONTEXT;
-  
-  if (!ctr) 
-    return CL_RET_NO_TRIGGER;
- 
-  if (ctr->t->flags & I3_TRIGGER_FLAG_RATE_LIMIT) {
-    assert(ctr->t->tb);
-    /* trigger is already rate limited; just update the token buket */
-    ctr->t->tb->type = type;
-    ctr->t->tb->depth = depth;
-    ctr->t->tb->r = r;
-    ctr->t->tb->R = R;
-    if (ctr->precomputed_pkt.p) {
-      free(ctr->precomputed_pkt.p);
-      /* need to precompute the packet after the change */
-      cl_make_trigger_packet(ctx, ctr->t, 
-                            I3_OPT_TRIGGER_INSERT, &ctr->precomputed_pkt);
-    }
-  } else {
-    ctr->t->flags |= I3_TRIGGER_FLAG_RATE_LIMIT;
-    ctr->t->tb = alloc_token_bucket();
-    init_token_bucket(ctr->t->tb, type, depth, r, R);
-  }
-  if (ctr->status == CL_TRIGGER_STATUS_INSERTED) {
-    /* update trigger token-bucket constraints */
-    cl_insert_trigger_into_i3(ctx, ctr);
-  }
-  return CL_RET_OK;
+        /* update trigger token-bucket constraints */
+        cl_insert_trigger_into_i3(ctx, ctr);
+    }
+    return CL_RET_OK;
 }
 
 //ADDED_DILIP
-int cl_ctx_register_trigger_callback(cl_context* ctx, cl_trigger *ctr, 
uint16_t cbk_type, 
-                                void (*fun)(void*,void *data, void *fun_ctx), 
void *fun_ctx)
-{
-  if (ctx == NULL)
-    return CL_RET_NO_CONTEXT;
-  
-  if (!ctr) 
-    return CL_RET_NO_TRIGGER;
- 
-  return cl_register_trigger_callback1(ctr, cbk_type, fun, fun_ctx);
-}
-
-int cl_ctx_register_fd_callback(cl_context *ctx, int fd, 
-                               int type, void (*fun)(int, void *), void *data)
-{
-  fd_node *n;
-
-  if (ctx == NULL)
-    return CL_RET_NO_CONTEXT;
-
-  switch (type) {
-  case CL_FD_TYPE_READ:
-    if ((n = get_fd_node(ctx->i3fds->readfd_list, fd))!=0)
-      return CL_RET_DUPLICATE_FD;
-    if ((n = alloc_fd_node(fd, fun, data)) == NULL)
-      /* just to please the compiler; alloc_fd_node will panic if it cannot
-       * allocate memory
-       */
-      return CL_RET_OK;
-    insert_fd_node_in_list(&ctx->i3fds->readfd_list, n);
-    break;
-  case CL_FD_TYPE_WRITE:
-    if ((n = get_fd_node(ctx->i3fds->writefd_list, fd))!=0)
-      return CL_RET_DUPLICATE_FD;
-    if ((n = alloc_fd_node(fd, fun, data)) == NULL)
-      return CL_RET_OK;
-    insert_fd_node_in_list(&ctx->i3fds->writefd_list, n);
-    break;
-  case CL_FD_TYPE_EXCEPT:
-    if ((n = get_fd_node(ctx->i3fds->exceptfd_list, fd))!=0)
-      return CL_RET_DUPLICATE_FD;
-    if ((n = alloc_fd_node(fd, fun, data)) == NULL)
-      return CL_RET_OK;
-    insert_fd_node_in_list(&ctx->i3fds->exceptfd_list, n);
-    break;
-  default:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_register_fd_callback: unknown 
file descriptor type\n");
-  }
-
-  ctx->i3fds->max_fd = MAX(ctx->i3fds->max_fd, fd);
-  
-  return CL_RET_OK;
-}
-
+int cl_ctx_register_trigger_callback(cl_context *ctx, cl_trigger *ctr, 
uint16_t cbk_type,
+                                     void (*fun)(void *, void *data, void 
*fun_ctx), void *fun_ctx)
+{
+    if (ctx == NULL) {
+        return CL_RET_NO_CONTEXT;
+    }
+
+    if (!ctr) {
+        return CL_RET_NO_TRIGGER;
+    }
+
+    return cl_register_trigger_callback1(ctr, cbk_type, fun, fun_ctx);
+}
+
+int cl_ctx_register_fd_callback(cl_context *ctx, int fd,
+                                int type, void (*fun)(int, void *), void *data)
+{
+    fd_node *n;
+
+    if (ctx == NULL) {
+        return CL_RET_NO_CONTEXT;
+    }
+
+    switch (type) {
+    case CL_FD_TYPE_READ:
+        if ((n = get_fd_node(ctx->i3fds->readfd_list, fd)) != 0) {
+            return CL_RET_DUPLICATE_FD;
+        }
+        if ((n = alloc_fd_node(fd, fun, data)) == NULL) {
+            /* just to please the compiler; alloc_fd_node will panic if it 
cannot
+             * allocate memory
+             */
+            return CL_RET_OK;
+        }
+        insert_fd_node_in_list(&ctx->i3fds->readfd_list, n);
+        break;
+    case CL_FD_TYPE_WRITE:
+        if ((n = get_fd_node(ctx->i3fds->writefd_list, fd)) != 0) {
+            return CL_RET_DUPLICATE_FD;
+        }
+        if ((n = alloc_fd_node(fd, fun, data)) == NULL) {
+            return CL_RET_OK;
+        }
+        insert_fd_node_in_list(&ctx->i3fds->writefd_list, n);
+        break;
+    case CL_FD_TYPE_EXCEPT:
+        if ((n = get_fd_node(ctx->i3fds->exceptfd_list, fd)) != 0) {
+            return CL_RET_DUPLICATE_FD;
+        }
+        if ((n = alloc_fd_node(fd, fun, data)) == NULL) {
+            return CL_RET_OK;
+        }
+        insert_fd_node_in_list(&ctx->i3fds->exceptfd_list, n);
+        break;
+    default:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_register_fd_callback: 
unknown file descriptor type\n");
+    }
+
+    ctx->i3fds->max_fd = MAX(ctx->i3fds->max_fd, fd);
+
+    return CL_RET_OK;
+}
 
 /************************************************************************
- * cl_ctx_unregister_fd_callback - unregister a callback associated with a
- *                                 file descriptor fd
- * NOTE: this should be done once the file descriptor is closed
- ************************************************************************/
+* cl_ctx_unregister_fd_callback - unregister a callback associated with a
+*                                 file descriptor fd
+* NOTE: this should be done once the file descriptor is closed
+************************************************************************/
 int cl_ctx_unregister_fd_callback(cl_context *ctx, int fd, int type)
 {
-  fd_node *n;
-
-  if (ctx == NULL)
-    return CL_RET_NO_CONTEXT;
-
-  switch (type) {
-  case CL_FD_TYPE_READ:
-    n = get_fd_node(ctx->i3fds->readfd_list, fd);
-    if (!n) 
-      return CL_RET_INVALID_FD;
-    remove_fd_node_from_list(&ctx->i3fds->readfd_list, n);
-    break;
-  case CL_FD_TYPE_WRITE:
-    n = get_fd_node(ctx->i3fds->writefd_list, fd);
-    if (!n) 
-      return CL_RET_INVALID_FD;
-    remove_fd_node_from_list(&ctx->i3fds->writefd_list, n);
-    break;
-  case CL_FD_TYPE_EXCEPT:
-    n = get_fd_node(ctx->i3fds->exceptfd_list, fd);
-    if (!n) 
-      return CL_RET_INVALID_FD;
-    remove_fd_node_from_list(&ctx->i3fds->exceptfd_list, n);
-    break;
-  default:
-    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_register_fd_callback: unknown 
file descriptor type\n");
-  }
-
-  compute_max_i3_fds(ctx->i3fds);
-
-  return CL_RET_OK;
+    fd_node *n;
+
+    if (ctx == NULL) {
+        return CL_RET_NO_CONTEXT;
+    }
+
+    switch (type) {
+    case CL_FD_TYPE_READ:
+        n = get_fd_node(ctx->i3fds->readfd_list, fd);
+        if (!n) {
+            return CL_RET_INVALID_FD;
+        }
+        remove_fd_node_from_list(&ctx->i3fds->readfd_list, n);
+        break;
+    case CL_FD_TYPE_WRITE:
+        n = get_fd_node(ctx->i3fds->writefd_list, fd);
+        if (!n) {
+            return CL_RET_INVALID_FD;
+        }
+        remove_fd_node_from_list(&ctx->i3fds->writefd_list, n);
+        break;
+    case CL_FD_TYPE_EXCEPT:
+        n = get_fd_node(ctx->i3fds->exceptfd_list, fd);
+        if (!n) {
+            return CL_RET_INVALID_FD;
+        }
+        remove_fd_node_from_list(&ctx->i3fds->exceptfd_list, n);
+        break;
+    default:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_register_fd_callback: 
unknown file descriptor type\n");
+    }
+
+    compute_max_i3_fds(ctx->i3fds);
+
+    return CL_RET_OK;
 }
 
-
 /***********************************************************************
  *  cl_ctx_set_timer - set timer
  *
@@ -534,90 +553,93 @@
  *           callback is invoked
  *
  ************************************************************************/
-cl_timer *cl_ctx_set_timer(cl_context *ctx, struct timeval *tv, 
-                          void (*fun)(void *), void *data)
+cl_timer *cl_ctx_set_timer(cl_context *ctx, struct timeval *tv,
+                           void (*fun)(void *), void *data)
 {
-  uint64_t when;
-  Event *ev;
-
-  if (ctx == NULL)
-    return NULL;
-
-  when = wall_time();
-  when = when + UMILLION*tv->tv_sec + tv->tv_usec;
-  ev = newEvent(fun, data, when);
-
-  insertEvent(&ctx->timer_heap, ev);
-
-  return (cl_timer *)ev;
+    uint64_t when;
+    Event *ev;
+
+    if (ctx == NULL) {
+        return NULL;
+    }
+
+    when = wall_time();
+    when = when + UMILLION * tv->tv_sec + tv->tv_usec;
+    ev   = newEvent(fun, data, when);
+
+    insertEvent(&ctx->timer_heap, ev);
+
+    return (cl_timer *) ev;
 }
 
 /**************************************************************************
  *  cl_ctx_send_stack - send packet to a stack of IDs
- *  
+ *
  *  input:
  *    ctx - context (only for cl_ctx_send)
  *    stack - stack, reppresented as an array of IDs; stack[0]
  *            represents the ID where the packet is sent next
- *    stack_len - number of IDs in the stack 
+ *    stack_len - number of IDs in the stack
  *    clb - payload
  *    flags - flags associated to sending a packet; possible values:
- *             CL_PKT_FLAG_ALLOW_SHORTCUT - allow shortcuts  
- *        
+ *             CL_PKT_FLAG_ALLOW_SHORTCUT - allow shortcuts
+ *
  *  return value:
  *    - error code; possible values:
  *        CL_RET_OK
  *        CL_RET_NO_CONTEXT
  *        CL_RET_INVALID_STACK_LEN
- *       CL_RET_MSG_SIZE
- *       CL_RET_NO_SERVERS
- *       CL_RET_NET_ERROR
+ *      CL_RET_MSG_SIZE
+ *      CL_RET_NO_SERVERS
+ *      CL_RET_NET_ERROR
  *************************************************************************/
-int cl_ctx_send_stack(cl_context *ctx, ID *stack, int stack_len, 
-                     cl_buf *clb, uint16_t flags)
+int cl_ctx_send_stack(cl_context *ctx, ID *stack, int stack_len,
+                      cl_buf *clb, uint16_t flags)
 {
-  i3_stack *s;
-  int err = 0;
-
-  if (ctx == NULL)
-    return CL_RET_NO_CONTEXT;
-  
-  if (stack_len == 0 || stack_len >= I3_MAX_STACK_LEN) 
-    return CL_RET_INVALID_STACK_LEN;
-
- 
-  s = alloc_i3_stack();
-  init_i3_stack(s, stack, stack_len);
-
-  // for now, setting is_total_len to "0"
-  err = cl_send_data_packet(ctx, s, clb, flags, 0);
-  free_i3_stack(s);
-
-  return err;
+    i3_stack *s;
+    int err = 0;
+
+    if (ctx == NULL) {
+        return CL_RET_NO_CONTEXT;
+    }
+
+    if (stack_len == 0 || stack_len >= I3_MAX_STACK_LEN) {
+        return CL_RET_INVALID_STACK_LEN;
+    }
+
+
+    s   = alloc_i3_stack();
+    init_i3_stack(s, stack, stack_len);
+
+    // for now, setting is_total_len to "0"
+    err = cl_send_data_packet(ctx, s, clb, flags, 0);
+    free_i3_stack(s);
+
+    return err;
 }
 
-
-
 /************************************************************************
  * Returns RTT of given addr (in host format)
  ***********************************************************************/
-int cl_ctx_get_rtt_server(cl_context* ctx, uint32_t addr, uint64_t *rtt)
+int cl_ctx_get_rtt_server(cl_context *ctx, uint32_t addr, uint64_t *rtt)
 {
-    if (ctx == NULL || ctx->list == NULL)
-       return CL_RET_NO_AUTO_SERVER_SELECT;
+    if (ctx == NULL || ctx->list == NULL) {
+        return CL_RET_NO_AUTO_SERVER_SELECT;
+    }
 
     *rtt = get_rtt(ctx->list, addr);
-    
+
     return CL_RET_OK;
 }
 
-int cl_ctx_get_rtt_id(cl_context* ctx, ID *id, uint64_t *rtt)
+int cl_ctx_get_rtt_id(cl_context *ctx, ID *id, uint64_t *rtt)
 {
-    if (ctx == NULL || ctx->list == NULL)
-       return CL_RET_NO_AUTO_SERVER_SELECT;
+    if (ctx == NULL || ctx->list == NULL) {
+        return CL_RET_NO_AUTO_SERVER_SELECT;
+    }
 
     *rtt = get_rtt_id(ctx->list, id);
-    
+
     return CL_RET_OK;
 }
 
@@ -627,37 +649,39 @@
  * At return, "k" would contain the actual number of servers that are
  * returned (may be smaller than requested)
  ***********************************************************************/
-int cl_ctx_get_top_k_servers(cl_context* ctx, int *k, uint32_t best_addr[],
-               uint16_t best_port[], uint64_t  best_rtt[])
-{ 
-    if (ctx == NULL || ctx->list == NULL) 
-       return CL_RET_NO_AUTO_SERVER_SELECT;
-    
+int cl_ctx_get_top_k_servers(cl_context *ctx, int *k, uint32_t best_addr[],
+                             uint16_t best_port[], uint64_t best_rtt[])
+{
+    if (ctx == NULL || ctx->list == NULL) {
+        return CL_RET_NO_AUTO_SERVER_SELECT;
+    }
+
     *k = get_top_k(ctx->list, *k, best_addr, best_port, best_rtt);
-   
-   //printf("in cl_get_top_k_servers, k returned = %d\n", *k); 
+
+    //printf("in cl_get_top_k_servers, k returned = %d\n", *k);
     return CL_RET_OK;
 }
 
-int cl_ctx_get_top_k_ids(cl_context* ctx,int *k, ID best_id[], uint64_t 
best_rtt[])
+int cl_ctx_get_top_k_ids(cl_context *ctx, int *k, ID best_id[], uint64_t 
best_rtt[])
 {
-    if (ctx == NULL || ctx->list == NULL)
-       return CL_RET_NO_AUTO_SERVER_SELECT;
+    if (ctx == NULL || ctx->list == NULL) {
+        return CL_RET_NO_AUTO_SERVER_SELECT;
+    }
 
     *k = get_top_k_id(ctx->list, *k, best_id, best_rtt);
-    
+
     return CL_RET_OK;
 }
 
-/** Close all the open sockets, including the ping socket 
+/** Close all the open sockets, including the ping socket
  */
-void i3_close_all_sockets (cl_context* ctx) {
-       
-       if (ctx->fd != -1) {
-               nw_close (ctx->fd);
-       }
-       if (ctx->is_tcp && ctx->tcp_fd != -1) {
-               nw_close (ctx->tcp_fd);
-       }
-       //close_ping_socket();
+void i3_close_all_sockets(cl_context *ctx)
+{
+    if (ctx->fd != -1) {
+        nw_close(ctx->fd);
+    }
+    if (ctx->is_tcp && ctx->tcp_fd != -1) {
+        nw_close(ctx->tcp_fd);
+    }
+    //close_ping_socket();
 }

=== modified file 'i3/i3_client/i3_client_api_ctx.h'
--- i3/i3_client/i3_client_api_ctx.h    2010-01-12 12:35:31 +0000
+++ i3/i3_client/i3_client_api_ctx.h    2010-02-11 11:49:47 +0000
@@ -1,9 +1,9 @@
 /***************************************************************************
-                          i3_client_api_ctx.h  -  description
-                             -------------------
-    begin                : Aug 20 2003
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
+*                         i3_client_api_ctx.h  -  description
+*                            -------------------
+*   begin                : Aug 20 2003
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
 
 #ifndef I3_CLIENT_API_CTX_H
 #define I3_CLIENT_API_CTX_H
@@ -19,14 +19,14 @@
 int cl_ctx_exit(cl_context *ctx);
 
 /*
- * cl_ctx_select - function that replaces the select() function 
- *             (sys/select.h) Either this function or cl_loop() should be 
- *             invoked at the end of every client program since 
- *             cl_select()/cl_loop() are responsibe with the trigger 
+ * cl_ctx_select - function that replaces the select() function
+ *             (sys/select.h) Either this function or cl_loop() should be
+ *             invoked at the end of every client program since
+ *             cl_select()/cl_loop() are responsibe with the trigger
  *             refreshing and processing the options of the received packets.
  */
 #define cl_ctx_select(ctx, n, readfds, writefds, exceptfds, cl_to) \
-  cl_context_select(ctx, n, readfds, writefds, exceptfds, cl_to)
+    cl_context_select(ctx, n, readfds, writefds, exceptfds, cl_to)
 int cl_ctx_loop(cl_context *ctx);
 
 
@@ -36,23 +36,23 @@
  *   CL_TRIGGER_CFLAG_L_CONSTRAINT - left constraint trigger
  *   CL_TRIGGER_CFLAG_PUBLIC - public trigger; otherwise the trigger
  *                             is private. If the trigger is public
- *                             then it has to be left constraint, 
- *                             i.e., CL_TRIGGER_CFLAG_R_CONSTRAINT 
+ *                             then it has to be left constraint,
+ *                             i.e., CL_TRIGGER_CFLAG_R_CONSTRAINT
  *                             and CL_TRIGGER_CFLAG_PUBLIC cannot be
  *                             used simultaneously
  */
 cl_trigger *cl_ctx_create_trigger(cl_context *ctx,
-                                 ID *id, uint16_t prefix_len, Key *key, 
-                                 uint16_t flags, int *rc);
+                                  ID *id, uint16_t prefix_len, Key *key,
+                                  uint16_t flags, int *rc);
 /* create a trigger pointing to a stack */
 cl_trigger *cl_ctx_create_trigger_stack(cl_context *ctx,
-                                       ID *id, uint16_t prefix_len, 
-                                       ID *stack, int stack_len, 
-                                       uint16_t flags, int *rc);
+                                        ID *id, uint16_t prefix_len,
+                                        ID *stack, int stack_len,
+                                        uint16_t flags, int *rc);
 /* destroy trigger */
 int cl_ctx_destroy_trigger(cl_context *ctx, cl_trigger *ctr);
 /* insert trigger into i3
- * Possible flags: 
+ * Possible flags:
  *   CL_IFLAGS_TRIGGER_LOCAL - trigger is only local, i.e., it is not inserted
  *                             into i3
  *   CL_IFLAGS_TRIGGER_ALLOW_SHORTCUT - allow shortcut
@@ -61,42 +61,41 @@
 
 #define cl_ctx_remove_trigger(ctx, ctr) cl_remove_trigger_from_i3(ctx, ctr)
 
-int cl_ctx_trigger_ratelimit(cl_context* ctx, cl_trigger *ctr, uint8_t type,
-                            uint32_t depth, uint32_t r, uint32_t R);
+int cl_ctx_trigger_ratelimit(cl_context *ctx, cl_trigger *ctr, uint8_t type,
+                             uint32_t depth, uint32_t r, uint32_t R);
 
 /* send functions */
-int cl_ctx_send_stack(cl_context *ctx, ID *stack, int stack_len, 
-                     cl_buf *clb, uint16_t flags);
+int cl_ctx_send_stack(cl_context *ctx, ID *stack, int stack_len,
+                      cl_buf *clb, uint16_t flags);
 #define cl_ctx_send(ctx, id, clb, flags) \
-  cl_ctx_send_to_stack(ctx, id, 1, clb, flags)
+    cl_ctx_send_to_stack(ctx, id, 1, clb, flags)
 
 
 /* register callback functions and timers */
 #define cl_ctx_register_callback(g_ctx, cbk_type, fun, fun_ctx) \
- cl_register_context_callback(g_ctx, cbk_type, fun, fun_ctx)
+    cl_register_context_callback(g_ctx, cbk_type, fun, fun_ctx)
 
 //ADDED_DILIP
-int cl_ctx_register_trigger_callback(cl_context *ctx, cl_trigger *ctr, 
uint16_t cbk_type, 
-                                void (*fun)(void* ctr, void* data, void* 
fun_ctx), void *fun_ctx); //DILIP
-
-
-int cl_ctx_register_fd_callback(cl_context *ctx, int fd, 
-                               int type, void (*fun)(int, void*), void *data);
+int cl_ctx_register_trigger_callback(cl_context * ctx, cl_trigger * ctr, 
uint16_t cbk_type,
+                                     void (*fun)(void *ctr, void *data, void 
*fun_ctx), void *fun_ctx); //DILIP
+
+
+int cl_ctx_register_fd_callback(cl_context * ctx, int fd,
+                                int type, void (*fun)(int, void *), void 
*data);
 int cl_ctx_unregister_fd_callback(cl_context *ctx, int fd, int type);
-cl_timer *cl_ctx_set_timer(cl_context *ctx, struct timeval *tv, 
-                          void (*fun)(void *), void *data);
+cl_timer *cl_ctx_set_timer(cl_context * ctx, struct timeval *tv,
+                           void (*fun)(void *), void *data);
 
-/* 
- * Get close servers from a list of servers 
+/*
+ * Get close servers from a list of servers
  *   - currently uses a combination of latitude-longitude + pings
  */
 int cl_ctx_get_rtt_server(cl_context *ctx, uint32_t addr, uint64_t *rtt);
 int cl_ctx_get_rtt_id(cl_context *ctx, ID *id, uint64_t *rtt);
-int cl_ctx_get_top_k_servers(cl_context* ctx, int *k, uint32_t best_addr[], 
uint16_t best_port[], uint64_t best_rtt[]);
-int cl_ctx_get_top_k_ids(cl_context* ctx, int *k, ID best_id[], uint64_t 
best_rtt[]);
-
-
-void i3_close_all_sockets (cl_context* ctx);
+int cl_ctx_get_top_k_servers(cl_context * ctx, int *k, uint32_t best_addr[], 
uint16_t best_port[], uint64_t best_rtt[]);
+int cl_ctx_get_top_k_ids(cl_context * ctx, int *k, ID best_id[], uint64_t 
best_rtt[]);
+
+
+void i3_close_all_sockets(cl_context *ctx);
 
 #endif // I3_CLIENT_API_CTX_H
-

=== modified file 'i3/i3_client/i3_client_api_ext.c'
--- i3/i3_client/i3_client_api_ext.c    2009-12-29 21:08:52 +0000
+++ i3/i3_client/i3_client_api_ext.c    2010-02-11 11:49:47 +0000
@@ -1,6 +1,6 @@
 #include "../i3/i3.h"
 
-#include <errno.h>    
+#include <errno.h>
 #include <time.h>
 #ifndef _WIN32
     #include <pthread.h>
@@ -18,9 +18,9 @@
 #include "i3_client_api_ctx.h"
 
 /**********************************************************************
- *
- **********************************************************************/
-int cl_init_ping(cl_context* ctx, char *url)
+*
+**********************************************************************/
+int cl_init_ping(cl_context *ctx, char *url)
 {
 #ifndef _WIN32
     pthread_t ping_thread;
@@ -32,34 +32,34 @@
     Coordinates coord;
     char *temp_str;
     int i;
-    
-    if (ctx == NULL)
-       return CL_RET_DUP_CONTEXT;
-    
-    ctx->list = (I3ServerList *) malloc(sizeof(I3ServerList));
+
+    if (ctx == NULL) {
+        return CL_RET_DUP_CONTEXT;
+    }
+
+    ctx->list            = (I3ServerList *) malloc(sizeof(I3ServerList));
     ctx->ping_start_time = (uint64_t *) malloc(sizeof(uint64_t));
     init_i3server_list(ctx->list);
 
-    coord.latitude = COORD_UNDEFINED; coord.longitude = COORD_UNDEFINED;
-    for (i = 0; i < ctx->num_servers; i++)
-      create_i3server(ctx->list, ctx->s_array[i].addr.s_addr,
-               ctx->s_array[i].port, ctx->s_array[i].id, coord);
-    
-    data = (PingThreadData *) malloc(sizeof(PingThreadData));
-    temp_str = (char *) malloc(strlen(url)+1);
+    coord.latitude       = COORD_UNDEFINED;
+    coord.longitude      = COORD_UNDEFINED;
+    for (i = 0; i < ctx->num_servers; i++) {
+        create_i3server(ctx->list, ctx->s_array[i].addr.s_addr,
+                        ctx->s_array[i].port, ctx->s_array[i].id, coord);
+    }
+
+    data                  = (PingThreadData *) malloc(sizeof(PingThreadData));
+    temp_str              = (char *) malloc(strlen(url) + 1);
     strcpy(temp_str, url);
-    data->url = temp_str;
-    data->list = ctx->list;
+    data->url             = temp_str;
+    data->list            = ctx->list;
     data->ping_start_time = ctx->ping_start_time;
 
 #ifndef _WIN32
-    pthread_create(&ping_thread, NULL, ping_thread_entry, (void *)data);
+    pthread_create(&ping_thread, NULL, ping_thread_entry, (void *) data);
     return CL_RET_OK;
 #else
-    err = _beginthreadex(NULL, 0, ping_thread_entry, (void *)data, 0, 
&ping_thread);
+    err = _beginthreadex(NULL, 0, ping_thread_entry, (void *) data, 0, 
&ping_thread);
     return (0 != err) ? CL_RET_OK : errno;
 #endif
 }
-
-
-

=== modified file 'i3/i3_client/i3_client_callback.c'
--- i3/i3_client/i3_client_callback.c   2010-01-06 22:17:32 +0000
+++ i3/i3_client/i3_client_callback.c   2010-02-11 11:49:47 +0000
@@ -1,9 +1,9 @@
 /***************************************************************************
-                          i3_client_callback.c  -  description
-                          -------------------
-    begin                : Aug 14 2003
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
+*                         i3_client_callback.c  -  description
+*                         -------------------
+*   begin                : Aug 14 2003
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
 
 #include "../i3/i3.h"
 #include "../i3/i3_fun.h"
@@ -12,7 +12,7 @@
 #include "../i3/i3_debug.h"
 
 
-//#define PRINT_DEF_CBK 
+//#define PRINT_DEF_CBK
 
 #ifdef CLIENT_API_DEPRECIATED
 #define TRG(x) (x->t)
@@ -21,15 +21,14 @@
 #endif
 
 
-void printf_def_cbk(char *str, ID *id, int intend) 
+void printf_def_cbk(char *str, ID *id, int intend)
 {
 #ifdef PRINT_DEF_CBK
-  I3_PRINT_DEBUG1(DEBUG_LEVEL_MINIMAL, "Default callback: %s\n", str);
-  printf_i3_id(id, intend);
+    I3_PRINT_DEBUG1(DEBUG_LEVEL_MINIMAL, "Default callback: %s\n", str);
+    printf_i3_id(id, intend);
 #endif
 }
 
-
 /***********************************************************************
  *  cl_trigger_callback - invoke a callback associated with a trigger
  *
@@ -44,135 +43,128 @@
  *
  ************************************************************************/
 
-void cl_trigger_callback(cl_context *ctx, cl_trigger *ctr, int cbk_type, 
-                        i3_header *hdr, cl_buf *cbl) 
+void cl_trigger_callback(cl_context *ctx, cl_trigger *ctr, int cbk_type,
+                         i3_header *hdr, cl_buf *cbl)
 {
-  switch (cbk_type) {
-  case CL_CBK_TRIGGER_INSERTED:
-    // printf("In Callback: trigger with following ID inserted\n");
-    // printf_i3_id(&(ctr->t->id), 2); 
-    if (ctr->cbk_trigger_inserted.fun) {
-      ctr->cbk_trigger_inserted.fun(TRG(ctr), 
-              NULL, ctr->cbk_trigger_inserted.fun_ctx);
-    } else if (ctx->cbk_trigger_inserted.fun) {
-      ctx->cbk_trigger_inserted.fun(TRG(ctr), 
-              NULL, ctx->cbk_trigger_inserted.fun_ctx);
-    } else {
-      printf_def_cbk("trigger with following ID inserted",
-                    &(ctr->t->id), 2); 
-    }
-    break;
-  case CL_CBK_TRIGGER_REFRESH_FAILED:
-    if (ctr->cbk_trigger_refresh_failed.fun) 
-      ctr->cbk_trigger_refresh_failed.fun(TRG(ctr), 
-                                         NULL, 
ctr->cbk_trigger_refresh_failed.fun_ctx);
-    else if (ctx->cbk_trigger_refresh_failed.fun)
-      ctx->cbk_trigger_refresh_failed.fun(TRG(ctr), 
-                                         NULL, 
ctx->cbk_trigger_refresh_failed.fun_ctx);
-    else {
-      printf_def_cbk("trigger with following ID couldn't be 
inserted/refreshed", 
-                    &(ctr->t->id), 2); 
-    }
-    break;
+    switch (cbk_type) {
+    case CL_CBK_TRIGGER_INSERTED:
+        // printf("In Callback: trigger with following ID inserted\n");
+        // printf_i3_id(&(ctr->t->id), 2);
+        if (ctr->cbk_trigger_inserted.fun) {
+            ctr->cbk_trigger_inserted.fun(TRG(ctr),
+                                          NULL, 
ctr->cbk_trigger_inserted.fun_ctx);
+        } else if (ctx->cbk_trigger_inserted.fun) {
+            ctx->cbk_trigger_inserted.fun(TRG(ctr),
+                                          NULL, 
ctx->cbk_trigger_inserted.fun_ctx);
+        } else {
+            printf_def_cbk("trigger with following ID inserted",
+                           &(ctr->t->id), 2);
+        }
+        break;
+    case CL_CBK_TRIGGER_REFRESH_FAILED:
+        if (ctr->cbk_trigger_refresh_failed.fun) {
+            ctr->cbk_trigger_refresh_failed.fun(TRG(ctr),
+                                                NULL, 
ctr->cbk_trigger_refresh_failed.fun_ctx);
+        } else if (ctx->cbk_trigger_refresh_failed.fun) {
+            ctx->cbk_trigger_refresh_failed.fun(TRG(ctr),
+                                                NULL, 
ctx->cbk_trigger_refresh_failed.fun_ctx);
+        } else {
+            printf_def_cbk("trigger with following ID couldn't be 
inserted/refreshed",
+                           &(ctr->t->id), 2);
+        }
+        break;
 
-  case CL_CBK_TRIGGER_CONSTRAINT_FAILED:
-        if (ctr->cbk_trigger_constraint_failed.fun)
-               ctr->cbk_trigger_constraint_failed.fun(TRG(ctr),
-                           NULL, ctr->cbk_trigger_constraint_failed.fun_ctx);
-        else if (ctx->cbk_trigger_constraint_failed.fun)
-               ctx->cbk_trigger_constraint_failed.fun(TRG(ctr),
-                           NULL, ctx->cbk_trigger_constraint_failed.fun_ctx);
-    else {
-      printf_def_cbk("trigger with following ID didn't satisfy constraints",
-                    &(ctr->t->id), 2);
-    }
-    break;
+    case CL_CBK_TRIGGER_CONSTRAINT_FAILED:
+        if (ctr->cbk_trigger_constraint_failed.fun) {
+            ctr->cbk_trigger_constraint_failed.fun(TRG(ctr),
+                                                   NULL, 
ctr->cbk_trigger_constraint_failed.fun_ctx);
+        } else if (ctx->cbk_trigger_constraint_failed.fun) {
+            ctx->cbk_trigger_constraint_failed.fun(TRG(ctr),
+                                                   NULL, 
ctx->cbk_trigger_constraint_failed.fun_ctx);
+        } else {
+            printf_def_cbk("trigger with following ID didn't satisfy 
constraints",
+                           &(ctr->t->id), 2);
+        }
+        break;
 
     case CL_CBK_RECEIVE_PACKET:
-        {
-            // The packet and its header to be passed to the callback function
-            // The callback function is responsible for freeing this memory.
-            static cbk_packet *tmp_cbk_pkt = NULL;
-            if (tmp_cbk_pkt == NULL) {
-                tmp_cbk_pkt = malloc(sizeof(cbk_packet));
-            }
-            tmp_cbk_pkt->ids = &(hdr->stack->ids[1]);
-            tmp_cbk_pkt->stack_len = hdr->stack->len - 1;
-            tmp_cbk_pkt->clb = cbl;
-  
-            if (hdr->stack->len <= 0) {
-                tmp_cbk_pkt->ids = NULL;
-            }
-
-
-            if (ctr->cbk_receive_packet.fun) 
-                   ctr->cbk_receive_packet.fun(TRG(ctr), tmp_cbk_pkt, 
-                                   ctr->cbk_receive_packet.fun_ctx);
-      
-            else if (ctx->cbk_receive_packet.fun)
-                   ctx->cbk_receive_packet.fun(TRG(ctr), tmp_cbk_pkt,
-                                   ctx->cbk_receive_packet.fun_ctx);
-            else {
-                   printf_def_cbk("received packet matching following ID",
-                           &(ctr->t->id), 2); 
-            }
-        }
+    {
+        // The packet and its header to be passed to the callback function
+        // The callback function is responsible for freeing this memory.
+        static cbk_packet *tmp_cbk_pkt = NULL;
+        if (tmp_cbk_pkt == NULL) {
+            tmp_cbk_pkt = malloc(sizeof(cbk_packet));
+        }
+        tmp_cbk_pkt->ids       = &(hdr->stack->ids[1]);
+        tmp_cbk_pkt->stack_len = hdr->stack->len - 1;
+        tmp_cbk_pkt->clb       = cbl;
+
+        if (hdr->stack->len <= 0) {
+            tmp_cbk_pkt->ids = NULL;
+        }
+
+
+        if (ctr->cbk_receive_packet.fun) {
+            ctr->cbk_receive_packet.fun(TRG(ctr), tmp_cbk_pkt,
+                                        ctr->cbk_receive_packet.fun_ctx);
+        } else if (ctx->cbk_receive_packet.fun) {
+            ctx->cbk_receive_packet.fun(TRG(ctr), tmp_cbk_pkt,
+                                        ctx->cbk_receive_packet.fun_ctx);
+        } else {
+            printf_def_cbk("received packet matching following ID",
+                           &(ctr->t->id), 2);
+        }
+    }
     break;
-  
+
     case CL_CBK_RECEIVE_PAYLOAD:
-        if (ctr->cbk_receive_packet.fun)
+        if (ctr->cbk_receive_packet.fun) {
             break;
-        
-        else if (ctr->cbk_receive_payload.fun)
+        } else if (ctr->cbk_receive_payload.fun) {
             ctr->cbk_receive_payload.fun(TRG(ctr), cbl,
-                                  ctr->cbk_receive_payload.fun_ctx);
-    
-        else if (ctx->cbk_receive_packet.fun)
+                                         ctr->cbk_receive_payload.fun_ctx);
+        } else if (ctx->cbk_receive_packet.fun) {
             break;
-        
-        else if (ctx->cbk_receive_payload.fun)
-            
-            ctx->cbk_receive_payload.fun(TRG(ctr), 
cbl,ctx->cbk_receive_payload.fun_ctx);
-        
-        else {
-            printf_def_cbk("received data matching following ID", 
-                        &(ctr->t->id), 2); 
+        } else if (ctx->cbk_receive_payload.fun) {
+            ctx->cbk_receive_payload.fun(TRG(ctr), cbl, 
ctx->cbk_receive_payload.fun_ctx);
+        } else {
+            printf_def_cbk("received data matching following ID",
+                           &(ctr->t->id), 2);
         }
-    break;
-    
+        break;
+
     case CL_CBK_ROUTE_BROKEN:
-        if (ctr->cbk_route_broken.fun) 
+        if (ctr->cbk_route_broken.fun) {
             ctr->cbk_route_broken.fun(TRG(ctr), NULL, 
ctr->cbk_route_broken.fun_ctx);
-        else if (ctx->cbk_route_broken.fun)
+        } else if (ctx->cbk_route_broken.fun) {
             ctx->cbk_route_broken.fun(TRG(ctr), NULL, 
ctx->cbk_route_broken.fun_ctx);
-        else {
+        } else {
 #ifdef PRINT_DEF_CBK
             I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, "Default callback: route 
broken while at the following trigger\n");
-            printf_i3_trigger(ctr->t, 2); 
+            printf_i3_trigger(ctr->t, 2);
 #endif // PRINT_DEF_CBK
-     }
-    break;
+        }
+        break;
 
     case CL_INTERNAL_HOOK_TRIGGER_ACK_TIMEOUT:
-        if (ctr->internal_hook_ack_timeout.fun)  {
-            ctr->internal_hook_ack_timeout.fun(TRG(ctr), 
-                                         NULL, 
ctr->internal_hook_ack_timeout.fun_ctx);
-
+        if (ctr->internal_hook_ack_timeout.fun) {
+            ctr->internal_hook_ack_timeout.fun(TRG(ctr),
+                                               NULL, 
ctr->internal_hook_ack_timeout.fun_ctx);
         }
-    break;
+        break;
 
     case CL_INTERNAL_HOOK_TRIGGER_REFRESH_TIMEOUT:
-        if (ctr->internal_hook_refresh_timeout.fun)  {
-            ctr->internal_hook_refresh_timeout.fun(TRG(ctr), 
-                                         NULL, 
ctr->internal_hook_refresh_timeout.fun_ctx);
+        if (ctr->internal_hook_refresh_timeout.fun) {
+            ctr->internal_hook_refresh_timeout.fun(TRG(ctr),
+                                                   NULL, 
ctr->internal_hook_refresh_timeout.fun_ctx);
         }
-    break;
-
-
-
-  default:
+        break;
+
+
+
+    default:
         I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_trigger_callback: invalid 
callback type!\n");
-  }
+    }
 }
 
 /***********************************************************************
@@ -185,51 +177,49 @@
  ************************************************************************/
 
 void cl_id_callback(cl_context *ctx, int cbk_type, ID *id,
-                   struct in_addr *ip_addr, uint16_t *port)
+                    struct in_addr *ip_addr, uint16_t *port)
 {
     switch (cbk_type) {
-        case CL_CBK_TRIGGER_NOT_FOUND:
-            if (ctx->cbk_trigger_not_found.fun)
-                ctx->cbk_trigger_not_found.fun(id, NULL, 
-                                    ctx->cbk_trigger_not_found.fun_ctx);
-            else {
-                printf_def_cbk("there is no trigger matching following ID", 
-                              id, 2); 
-            }
-        break;
-  
-        case CL_CBK_RATELIMIT_EXCEEDED:
-            if (ctx->cbk_ratelimit_exceeded.fun)
-                ctx->cbk_ratelimit_exceeded.fun(id, NULL, 
-                                    ctx->cbk_ratelimit_exceeded.fun_ctx);
-            else {
-                printf_def_cbk("token-bucket constraints violated for ID", 
-                              id, 2); 
-            }
-        break;
-  
-        case CL_CBK_SERVER_DOWN:
-            if (ctx->cbk_server_down.fun) {
-                ctx->cbk_server_down.fun(ip_addr, port, 
ctx->cbk_server_down.fun_ctx);
-            } else {
-      
+    case CL_CBK_TRIGGER_NOT_FOUND:
+        if (ctx->cbk_trigger_not_found.fun) {
+            ctx->cbk_trigger_not_found.fun(id, NULL,
+                                           ctx->cbk_trigger_not_found.fun_ctx);
+        } else {
+            printf_def_cbk("there is no trigger matching following ID",
+                           id, 2);
+        }
+        break;
+
+    case CL_CBK_RATELIMIT_EXCEEDED:
+        if (ctx->cbk_ratelimit_exceeded.fun) {
+            ctx->cbk_ratelimit_exceeded.fun(id, NULL,
+                                            
ctx->cbk_ratelimit_exceeded.fun_ctx);
+        } else {
+            printf_def_cbk("token-bucket constraints violated for ID",
+                           id, 2);
+        }
+        break;
+
+    case CL_CBK_SERVER_DOWN:
+        if (ctx->cbk_server_down.fun) {
+            ctx->cbk_server_down.fun(ip_addr, port, 
ctx->cbk_server_down.fun_ctx);
+        } else {
 #ifdef PRINT_DEF_CBK
-                ip_addr->s_addr = htonl(ip_addr->s_addr);
-                I3_PRINT_DEBUG2(I3_DEBUG_LEVEL_MINIMAL, "Default callback: 
server couldn't be contacted (%s, %d)\n", 
-                           inet_ntoa(*ip_addr), *port);
-                ip_addr->s_addr = ntohl(ip_addr->s_addr);
+            ip_addr->s_addr = htonl(ip_addr->s_addr);
+            I3_PRINT_DEBUG2(I3_DEBUG_LEVEL_MINIMAL, "Default callback: server 
couldn't be contacted (%s, %d)\n",
+                            inet_ntoa(*ip_addr), *port);
+            ip_addr->s_addr = ntohl(ip_addr->s_addr);
 #endif
-            }
+        }
         break;
-  
-        default:
-            I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_callback: invalid 
callback type!\n");
+
+    default:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_callback: invalid callback 
type!\n");
     }
 }
 
-
 /************************************************************************
- *  cl_register_trigger_callback1 - associate a callback with a trigger 
+ *  cl_register_trigger_callback1 - associate a callback with a trigger
  *
  *  input:
  *    ctr - trigger
@@ -239,84 +229,82 @@
  *************************************************************************/
 
 int cl_register_trigger_callback1(cl_trigger *ctr, uint16_t cbk_type,
-                       void (*fun)(void*, void* data, void *fun_ctx),
-            void *fun_ctx)
+                                  void (*fun)(void *, void *data, void 
*fun_ctx),
+                                  void *fun_ctx)
 {
-  
     switch (cbk_type) {
-        case CL_CBK_TRIGGER_INSERTED:
-            if (ctr->type == CL_TRIGGER_LOCAL) {
-                // local triggers are not inserted in i3
-                return CL_RET_INVALID_TRIGGER_TYPE;
-            }
-            ctr->cbk_trigger_inserted.fun = fun;
-            ctr->cbk_trigger_inserted.fun_ctx = fun_ctx;
-        break;
-  
-        case CL_CBK_TRIGGER_REFRESH_FAILED:
-            if (ctr->type == CL_TRIGGER_LOCAL) {
-                // local triggers are not inserted in i3
-                return CL_RET_INVALID_TRIGGER_TYPE;
-            }
-    
-            ctr->cbk_trigger_refresh_failed.fun = fun;
-            ctr->cbk_trigger_refresh_failed.fun_ctx = fun_ctx;
-        break;
-  
-        case CL_CBK_TRIGGER_CONSTRAINT_FAILED:
-            if (ctr->type == CL_TRIGGER_LOCAL) {
-                // local triggers are not inserted in i3
-                return CL_RET_INVALID_TRIGGER_TYPE;
-            }
-    
-            ctr->cbk_trigger_constraint_failed.fun = fun;
-            ctr->cbk_trigger_constraint_failed.fun_ctx = fun_ctx;
-        break;
-  
-        case CL_CBK_RECEIVE_PACKET:
-            ctr->cbk_receive_packet.fun = fun;
-            ctr->cbk_receive_packet.fun_ctx = fun_ctx;
-            /* this callback takes precedence over 
-            * CL_CBK_RECEIVE_PAYLOAD callback */
-            if (ctr->cbk_receive_payload.fun) {
-                return CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD;
-            }
-        break;
-  
-        case CL_CBK_RECEIVE_PAYLOAD:
-            ctr->cbk_receive_payload.fun = fun;
-            ctr->cbk_receive_payload.fun_ctx = fun_ctx;
-            /* this callback is ignored if CL_CBK_RECEIVE_PACKET is already 
defined */
-            if (ctr->cbk_receive_packet.fun) {
-                return CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD;
-            }
-        break;
-  
-        case CL_CBK_ROUTE_BROKEN:
-            ctr->cbk_route_broken.fun = fun;
-            ctr->cbk_route_broken.fun_ctx = fun_ctx;
-        break;
-
-        case CL_INTERNAL_HOOK_TRIGGER_ACK_TIMEOUT:
-            ctr->internal_hook_ack_timeout.fun = fun;
-            ctr->internal_hook_ack_timeout.fun_ctx = fun_ctx;
-        break;
-        
-        case CL_INTERNAL_HOOK_TRIGGER_REFRESH_TIMEOUT:
-            ctr->internal_hook_refresh_timeout.fun = fun;
-            ctr->internal_hook_refresh_timeout.fun_ctx = fun_ctx;
-        break;
-        
-        default:
-            panic("cl_cbk_register_trigger_callback: invalid callback 
type!\n");
+    case CL_CBK_TRIGGER_INSERTED:
+        if (ctr->type == CL_TRIGGER_LOCAL) {
+            // local triggers are not inserted in i3
+            return CL_RET_INVALID_TRIGGER_TYPE;
+        }
+        ctr->cbk_trigger_inserted.fun     = fun;
+        ctr->cbk_trigger_inserted.fun_ctx = fun_ctx;
+        break;
+
+    case CL_CBK_TRIGGER_REFRESH_FAILED:
+        if (ctr->type == CL_TRIGGER_LOCAL) {
+            // local triggers are not inserted in i3
+            return CL_RET_INVALID_TRIGGER_TYPE;
+        }
+
+        ctr->cbk_trigger_refresh_failed.fun     = fun;
+        ctr->cbk_trigger_refresh_failed.fun_ctx = fun_ctx;
+        break;
+
+    case CL_CBK_TRIGGER_CONSTRAINT_FAILED:
+        if (ctr->type == CL_TRIGGER_LOCAL) {
+            // local triggers are not inserted in i3
+            return CL_RET_INVALID_TRIGGER_TYPE;
+        }
+
+        ctr->cbk_trigger_constraint_failed.fun     = fun;
+        ctr->cbk_trigger_constraint_failed.fun_ctx = fun_ctx;
+        break;
+
+    case CL_CBK_RECEIVE_PACKET:
+        ctr->cbk_receive_packet.fun                = fun;
+        ctr->cbk_receive_packet.fun_ctx            = fun_ctx;
+        /* this callback takes precedence over
+         * CL_CBK_RECEIVE_PAYLOAD callback */
+        if (ctr->cbk_receive_payload.fun) {
+            return CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD;
+        }
+        break;
+
+    case CL_CBK_RECEIVE_PAYLOAD:
+        ctr->cbk_receive_payload.fun     = fun;
+        ctr->cbk_receive_payload.fun_ctx = fun_ctx;
+        /* this callback is ignored if CL_CBK_RECEIVE_PACKET is already 
defined */
+        if (ctr->cbk_receive_packet.fun) {
+            return CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD;
+        }
+        break;
+
+    case CL_CBK_ROUTE_BROKEN:
+        ctr->cbk_route_broken.fun                  = fun;
+        ctr->cbk_route_broken.fun_ctx              = fun_ctx;
+        break;
+
+    case CL_INTERNAL_HOOK_TRIGGER_ACK_TIMEOUT:
+        ctr->internal_hook_ack_timeout.fun         = fun;
+        ctr->internal_hook_ack_timeout.fun_ctx     = fun_ctx;
+        break;
+
+    case CL_INTERNAL_HOOK_TRIGGER_REFRESH_TIMEOUT:
+        ctr->internal_hook_refresh_timeout.fun     = fun;
+        ctr->internal_hook_refresh_timeout.fun_ctx = fun_ctx;
+        break;
+
+    default:
+        panic("cl_cbk_register_trigger_callback: invalid callback type!\n");
     }
-    
+
     return CL_RET_OK;
 }
 
-
 /************************************************************************
- *  cl_register_context_callback - associate a callback with a context 
+ *  cl_register_context_callback - associate a callback with a context
  *
  *  input:
  *    ctr - trigger
@@ -326,71 +314,68 @@
  *************************************************************************/
 
 int cl_register_context_callback(cl_context *ctx, uint16_t cbk_type,
-               void (*fun)(void *ctx_data, void *data, void* fun_ctx),
-        void * fun_ctx)
+                                 void (*fun)(void *ctx_data, void *data, void 
*fun_ctx),
+                                 void *fun_ctx)
 {
-  
     switch (cbk_type) {
-        case CL_CBK_TRIGGER_NOT_FOUND:
-            ctx->cbk_trigger_not_found.fun = fun;
-            ctx->cbk_trigger_not_found.fun_ctx = fun_ctx;
-           break;
-        
-        case CL_CBK_TRIGGER_INSERTED:
-            ctx->cbk_trigger_inserted.fun = fun;
-            ctx->cbk_trigger_inserted.fun_ctx = fun_ctx;
-           break;
-    
-        case CL_CBK_TRIGGER_REFRESH_FAILED:
-            ctx->cbk_trigger_refresh_failed.fun = fun;
-            ctx->cbk_trigger_refresh_failed.fun_ctx = fun_ctx;
-           break;
-    
-        case CL_CBK_TRIGGER_CONSTRAINT_FAILED:
-            ctx->cbk_trigger_constraint_failed.fun = fun;
-            ctx->cbk_trigger_constraint_failed.fun_ctx = fun_ctx;
-           break;
-    
-        case CL_CBK_RECEIVE_PACKET:
-            ctx->cbk_receive_packet.fun = fun;
-            ctx->cbk_receive_packet.fun_ctx = fun_ctx;
-            /* this callback takes precedence over 
-            * CL_CBK_RECEIVE_PAYLOAD callback 
-            */
-    
-            if (ctx->cbk_receive_payload.fun) {
-                return CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD;
-            }
-           break;
-  
-        case CL_CBK_RECEIVE_PAYLOAD:
-            ctx->cbk_receive_payload.fun = fun;
-            ctx->cbk_receive_payload.fun_ctx = fun_ctx;
-            /* this callback is ignored if CL_CBK_RECEIVE_PACKET is already 
defined */
-            if (ctx->cbk_receive_packet.fun) {
-                return CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD;
-            }
-           break;
-  
-        case CL_CBK_ROUTE_BROKEN:
-            ctx->cbk_route_broken.fun = fun;
-            ctx->cbk_route_broken.fun_ctx = fun_ctx;
-           break;
-    
-        case CL_CBK_SERVER_DOWN:
-            ctx->cbk_server_down.fun = fun; 
-            ctx->cbk_server_down.fun_ctx = fun_ctx;
-           break;
-    
-        case CL_CBK_RATELIMIT_EXCEEDED:
-            ctx->cbk_ratelimit_exceeded.fun = fun;
-            ctx->cbk_ratelimit_exceeded.fun_ctx = fun_ctx;
-           break;
-        
-        default:
-            I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, 
"cl_register_context_callback: invalid callback type!\n");
-  }
-  return CL_RET_OK;
+    case CL_CBK_TRIGGER_NOT_FOUND:
+        ctx->cbk_trigger_not_found.fun             = fun;
+        ctx->cbk_trigger_not_found.fun_ctx         = fun_ctx;
+        break;
+
+    case CL_CBK_TRIGGER_INSERTED:
+        ctx->cbk_trigger_inserted.fun              = fun;
+        ctx->cbk_trigger_inserted.fun_ctx          = fun_ctx;
+        break;
+
+    case CL_CBK_TRIGGER_REFRESH_FAILED:
+        ctx->cbk_trigger_refresh_failed.fun        = fun;
+        ctx->cbk_trigger_refresh_failed.fun_ctx    = fun_ctx;
+        break;
+
+    case CL_CBK_TRIGGER_CONSTRAINT_FAILED:
+        ctx->cbk_trigger_constraint_failed.fun     = fun;
+        ctx->cbk_trigger_constraint_failed.fun_ctx = fun_ctx;
+        break;
+
+    case CL_CBK_RECEIVE_PACKET:
+        ctx->cbk_receive_packet.fun                = fun;
+        ctx->cbk_receive_packet.fun_ctx            = fun_ctx;
+        /* this callback takes precedence over
+         * CL_CBK_RECEIVE_PAYLOAD callback
+         */
+
+        if (ctx->cbk_receive_payload.fun) {
+            return CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD;
+        }
+        break;
+
+    case CL_CBK_RECEIVE_PAYLOAD:
+        ctx->cbk_receive_payload.fun     = fun;
+        ctx->cbk_receive_payload.fun_ctx = fun_ctx;
+        /* this callback is ignored if CL_CBK_RECEIVE_PACKET is already 
defined */
+        if (ctx->cbk_receive_packet.fun) {
+            return CL_RET_IGNORE_CBK_RECEIVE_PAYLOAD;
+        }
+        break;
+
+    case CL_CBK_ROUTE_BROKEN:
+        ctx->cbk_route_broken.fun           = fun;
+        ctx->cbk_route_broken.fun_ctx       = fun_ctx;
+        break;
+
+    case CL_CBK_SERVER_DOWN:
+        ctx->cbk_server_down.fun            = fun;
+        ctx->cbk_server_down.fun_ctx        = fun_ctx;
+        break;
+
+    case CL_CBK_RATELIMIT_EXCEEDED:
+        ctx->cbk_ratelimit_exceeded.fun     = fun;
+        ctx->cbk_ratelimit_exceeded.fun_ctx = fun_ctx;
+        break;
+
+    default:
+        I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_register_context_callback: 
invalid callback type!\n");
+    }
+    return CL_RET_OK;
 }
-
-

=== modified file 'i3/i3_client/i3_client_callback.h'
--- i3/i3_client/i3_client_callback.h   2010-01-06 22:17:32 +0000
+++ i3/i3_client/i3_client_callback.h   2010-02-11 11:49:47 +0000
@@ -1,25 +1,25 @@
 /***************************************************************************
-                          i3_client_callback.h  -  description
-                             -------------------
-    begin                :  Aug 14 2003
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
+*                         i3_client_callback.h  -  description
+*                            -------------------
+*   begin                :  Aug 14 2003
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
 
 #ifndef I3_CLIENT_CALLBACK_H
 #define I3_CLIENT_CALLBACK_H
 int cl_register_context_callback(
-                cl_context *ctx, uint16_t cbk_type, 
-                                void (*fun)(void *ctx_data, void *data, void* 
fun_ctx), 
-                 void *fun_ctx);
-
-int cl_register_trigger_callback1(cl_trigger *clt, uint16_t cbk_type,
-                                 void (*fun)(void*, void* data, void* fun_ctx),
-                  void *fun_ctx);
-
-
-void cl_trigger_callback(cl_context *ctx, cl_trigger *ctr, 
-                        int cbk_type, i3_header *hdr, cl_buf *clb);
+    cl_context * ctx, uint16_t cbk_type,
+    void (*fun)(void *ctx_data, void *data, void *fun_ctx),
+    void *fun_ctx);
+
+int cl_register_trigger_callback1(cl_trigger * clt, uint16_t cbk_type,
+                                  void (*fun)(void *, void *data, void 
*fun_ctx),
+                                  void *fun_ctx);
+
+
+void cl_trigger_callback(cl_context *ctx, cl_trigger *ctr,
+                         int cbk_type, i3_header *hdr, cl_buf *clb);
 void cl_id_callback(cl_context *ctx, int cbk_type, ID *id,
-                   struct in_addr *addr, uint16_t *port);
+                    struct in_addr *addr, uint16_t *port);
 
 #endif

=== modified file 'i3/i3_client/i3_client_context.c'
--- i3/i3_client/i3_client_context.c    2010-01-12 12:35:31 +0000
+++ i3/i3_client/i3_client_context.c    2010-02-11 11:49:47 +0000
@@ -1,14 +1,14 @@
 /***************************************************************************
-                          i3_client_context.c  -  description
-                             -------------------
-    begin                :  Aug 14 2003
-    email                : istoica@xxxxxxxxxxxxxxx
-
-    changes: 
-      Nov 10, 2004: - handle the anycast triggers inserted by the same node
-                      (in cl_context_select)
-             
- ***************************************************************************/
+*                         i3_client_context.c  -  description
+*                            -------------------
+*   begin                :  Aug 14 2003
+*   email                : istoica@xxxxxxxxxxxxxxx
+*
+*   changes:
+*     Nov 10, 2004: - handle the anycast triggers inserted by the same node
+*                     (in cl_context_select)
+*
+***************************************************************************/
 
 #include <stdio.h>
 #include <stdarg.h>
@@ -48,846 +48,862 @@
 
 int does_id_match(ID *id1, ID *id2, int prefix_len);
 
-void close_tcp(cl_context *ctx) {
+void close_tcp(cl_context *ctx)
+{
+    printf("\nClosing fd = %d\n", ctx->tcp_fd);
+    nw_close(ctx->tcp_fd);
 
-  printf ("\nClosing fd = %d\n", ctx->tcp_fd);
-  nw_close(ctx->tcp_fd);
- 
-  ctx->init_tcp_ctx_flag = 0; //TCP socket is not initialized.
+    ctx->init_tcp_ctx_flag = 0; //TCP socket is not initialized.
 }
 
 /**
-  * This function initializes the TCP socket used to communicate
-  * with the first hop i3 server, if UseTCP is set in the configuration file
-  * @author Dilip
-  */
-void init_tcp_ctx(cl_context* ctx) {
-  int idx;
-  struct sockaddr_in server_addr;
-  
-  if (ctx->is_tcp) {
-    fprintf(stderr, "Warning: Mobility using TCP unsupported\n");
-    
-    if (ctx->init_tcp_ctx_flag)
-      close_tcp(ctx); // make sure that there isn't a TCP connection
-                      // in inconsistent state
-    if ((ctx->tcp_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-      perror("socket");
-      I3_PRINT_INFO1(I3_INFO_LEVEL_WARNING, 
-                "Failed to create TCP socket (errno = %d)\n", errno);
-      ctx->init_tcp_ctx_flag = 0;
-      return;
-    }
-        
-    printf("open TCP socket = %d\n", ctx->tcp_fd); // XXX
-    if (bind(ctx->tcp_fd, (struct sockaddr *) &ctx->local, 
-            sizeof(struct sockaddr_in)) < 0) { 
-      I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, 
-                 "cl_init_context: TCP bind (errno = %d)\n", errno);
-      close_tcp(ctx);
-      return;
-    }
-
-    /* Get server from the list and connect to it
-     * For now, it is assumed that there is only one server on the
-     * list and (obviously) that is the first hop i3 server 
-     */
-    idx = get_i3_server(ctx->num_servers, ctx->s_array);
-    if (idx < 0) {
-      if (!ctx->use_ping) {
-       I3_PRINT_INFO0 (I3_INFO_LEVEL_FATAL_ERROR, 
-                   "There are no known i3 servers specified in the 
configuration file "
-                   "and UsePing is deactivated.  So there is no way I can get 
to know "
-                   "about an i3 server.\nPlease turn on UsePing or specify i3 
server "
-                   "details in the i3 configuration file.\n"
-                    );
-       EXIT_ON_ERROR;
-      }
-      close_tcp(ctx);
-      return;
-
-      //TODO fix i3 client API to include timer to reattempt tcp init later.
-    }
-    
-    memset(&server_addr, 0, sizeof(struct sockaddr_in));
-    server_addr.sin_family = AF_INET;
-    server_addr.sin_addr.s_addr = htonl(ctx->s_array[idx].addr.s_addr);
-    server_addr.sin_port = htons(ctx->s_array[idx].port);
-       
-    I3_PRINT_INFO1 (I3_INFO_LEVEL_MINIMAL,
-                "I3 OC-D trying to connect to %s via TCP.\n", 
-                inet_ntoa (((struct sockaddr_in *) &server_addr)->sin_addr));
-                
-    if (connect(ctx->tcp_fd, (struct sockaddr *)&server_addr, 
-               sizeof(struct sockaddr_in)) < 0) {
-      I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL, 
-                 "cl_init_context: TCP connect error (errno = %d)\n", errno);
-      close_tcp(ctx);; 
-    } else {
-      I3_PRINT_INFO1(I3_INFO_LEVEL_MINIMAL,
-                "I3 OC-D connected to %s via TCP.\n", 
-                inet_ntoa (((struct sockaddr_in *) &server_addr)->sin_addr));
-      ctx->init_tcp_ctx_flag = 1; //TCP socket was initialized.
-    }
-  }
-} 
-
+ * This function initializes the TCP socket used to communicate
+ * with the first hop i3 server, if UseTCP is set in the configuration file
+ * @author Dilip
+ */
+void init_tcp_ctx(cl_context *ctx)
+{
+    int idx;
+    struct sockaddr_in server_addr;
+
+    if (ctx->is_tcp) {
+        fprintf(stderr, "Warning: Mobility using TCP unsupported\n");
+
+        if (ctx->init_tcp_ctx_flag) {
+            close_tcp(ctx); // make sure that there isn't a TCP connection
+        }
+        // in inconsistent state
+        if ((ctx->tcp_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+            perror("socket");
+            I3_PRINT_INFO1(I3_INFO_LEVEL_WARNING,
+                           "Failed to create TCP socket (errno = %d)\n", 
errno);
+            ctx->init_tcp_ctx_flag = 0;
+            return;
+        }
+
+        printf("open TCP socket = %d\n", ctx->tcp_fd); // XXX
+        if (bind(ctx->tcp_fd, (struct sockaddr *) &ctx->local,
+                 sizeof(struct sockaddr_in)) < 0) {
+            I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL,
+                            "cl_init_context: TCP bind (errno = %d)\n", errno);
+            close_tcp(ctx);
+            return;
+        }
+
+        /* Get server from the list and connect to it
+         * For now, it is assumed that there is only one server on the
+         * list and (obviously) that is the first hop i3 server
+         */
+        idx = get_i3_server(ctx->num_servers, ctx->s_array);
+        if (idx < 0) {
+            if (!ctx->use_ping) {
+                I3_PRINT_INFO0(I3_INFO_LEVEL_FATAL_ERROR,
+                               "There are no known i3 servers specified in the 
configuration file "
+                               "and UsePing is deactivated.  So there is no 
way I can get to know "
+                               "about an i3 server.\nPlease turn on UsePing or 
specify i3 server "
+                               "details in the i3 configuration file.\n"
+                               );
+                EXIT_ON_ERROR;
+            }
+            close_tcp(ctx);
+            return;
+
+            //TODO fix i3 client API to include timer to reattempt tcp init 
later.
+        }
+
+        memset(&server_addr, 0, sizeof(struct sockaddr_in));
+        server_addr.sin_family      = AF_INET;
+        server_addr.sin_addr.s_addr = htonl(ctx->s_array[idx].addr.s_addr);
+        server_addr.sin_port        = htons(ctx->s_array[idx].port);
+
+        I3_PRINT_INFO1(I3_INFO_LEVEL_MINIMAL,
+                       "I3 OC-D trying to connect to %s via TCP.\n",
+                       inet_ntoa(((struct sockaddr_in *) 
&server_addr)->sin_addr));
+
+        if (connect(ctx->tcp_fd, (struct sockaddr *) &server_addr,
+                    sizeof(struct sockaddr_in)) < 0) {
+            I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_MINIMAL,
+                            "cl_init_context: TCP connect error (errno = 
%d)\n", errno);
+            close_tcp(ctx);
+            ;
+        } else {
+            I3_PRINT_INFO1(I3_INFO_LEVEL_MINIMAL,
+                           "I3 OC-D connected to %s via TCP.\n",
+                           inet_ntoa(((struct sockaddr_in *) 
&server_addr)->sin_addr));
+            ctx->init_tcp_ctx_flag = 1; //TCP socket was initialized.
+        }
+    }
+}
 
 /***************************************************************************
- *  cl_create_context - allocate and initialize i3 client context. the context 
- *                      maintains the address of a default i3 server and the 
- *                      list of the triggers inserted by the client
- *
- *  input:
- *    local_ip_addr, local_port - local IP address and port where 
- *       i3 packets are to be received (in host format)
- *
- *  return:
- *    allocated context
- ***************************************************************************/
+*  cl_create_context - allocate and initialize i3 client context. the context
+*                      maintains the address of a default i3 server and the
+*                      list of the triggers inserted by the client
+*
+*  input:
+*    local_ip_addr, local_port - local IP address and port where
+*       i3 packets are to be received (in host format)
+*
+*  return:
+*    allocated context
+***************************************************************************/
 
 cl_context *cl_create_context(struct in_addr *local_ip_addr,
-                             uint16_t local_port)
+                              uint16_t local_port)
 {
-  cl_context   *ctx;
-  uint8_t      opt_mask;
-  int bind_ret_val;
-  
-  aeshash_init();
-
-  if (local_port == 0) {
-    local_port = unif_rand(MIN_PORT_NUM, MAX_PORT_NUM);
-    I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_VERBOSE, "i3 port number: %d\n", 
local_port);
-  }
-
-  if (!(ctx = (cl_context *)calloc(1, sizeof(cl_context))))
+    cl_context *ctx;
+    uint8_t opt_mask;
+    int bind_ret_val;
+
+    aeshash_init();
+
+    if (local_port == 0) {
+        local_port = unif_rand(MIN_PORT_NUM, MAX_PORT_NUM);
+        I3_PRINT_DEBUG1(I3_DEBUG_LEVEL_VERBOSE, "i3 port number: %d\n", 
local_port);
+    }
+
+    if (!(ctx = (cl_context *) calloc(1, sizeof(cl_context)))) {
         I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_init_context: memory 
allocation error (1)\n");
-
-  uint64_to_tval(&ctx->now, wall_time());
-
-  if (!(ctx->s_array = (srv_address *)calloc(MAX_NUM_SRV,sizeof(srv_address))))
+    }
+
+    uint64_to_tval(&ctx->now, wall_time());
+
+    if (!(ctx->s_array = (srv_address *) calloc(MAX_NUM_SRV, 
sizeof(srv_address)))) {
         I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_init_context: memory 
allocation error (2)\n");
-
-  /* read the list of i3 server addreses from the configuration file */
-  read_srv_list(ctx);
-
-  /* create field descriptor and address data structure to 
-   * receive i3 traffic */
-
-  {
-       int tmpFD = socket (AF_INET, SOCK_DGRAM, 0);
-       char*tmp;
-       if (tmpFD < 0) {
-               perror ("socket");
-               I3_PRINT_DEBUG1 ( I3_DEBUG_LEVEL_WARNING,
-                               "Unable to open i3 UDP socket: %s.\n",
-                               strerror (errno)
-                       );
-               tmp = strerror (errno);
-
-                         switch (errno) {
-                                       case EBADF:
-                                               printf ("EBADF\n");
-                                       break;
-                                       case EINVAL:
-                                               printf ("EINVAL\n");
-                                       break;
-                                       case EACCES:
-                                               printf ("EACCES\n");
-                                       break;
-                                       case ENOTSOCK:
-                                               printf ("ENOTSOCK\n");
-                                       break;
-                                       case EROFS:
-                                               printf ("EROFS  \n");
-                                       break;
-               
-                                       case EFAULT:
-                                               printf ("EFAULT\n");
-                                       break;
-
-                                       case ENAMETOOLONG:
-                                               printf ("ENAMETOOLONG\n");
-                                       break;  
-                                       case ENOENT:
-                                               printf ("ENOENT\n");
-                                       break;
-                                       case ENOMEM:
-                                               printf ("ENOMEME\n");
-                                       break;
-                         }
-                       exit(-1);
-       } else {
-               ctx->fd = tmpFD;
-       }
-  }
-
-  
-
-  memset(&ctx->local, 0, sizeof(struct sockaddr_in));
-  ctx->local.sin_family = AF_INET;
-  ctx->local.sin_addr.s_addr = htonl(INADDR_ANY);
-  ctx->local.sin_port = htons(local_port);
-    
-  /* bind to the port */
-
-  if ((bind_ret_val = bind(ctx->fd, (struct sockaddr *) &ctx->local,  
sizeof(struct sockaddr_in))) < 0) {
-               
-         switch (bind_ret_val) {
-               case EBADF:
-                   printf ("EBADF\n");
-               break;
-               case EINVAL:
-                       printf ("EINVAL\n");
-               break;
-               case EACCES:
-                       printf ("EACCES\n");
-               break;
-               case ENOTSOCK:
-                       printf ("ENOTSOCK\n");
-               break;
-               case EROFS:
-                       printf ("EROFS  \n");
-               break;
-               
-               case EFAULT:
-                       printf ("EFAULT\n");
-               break;
-
-               case ENAMETOOLONG:
-                       printf ("ENAMETOOLONG\n");
-               break;  
-               case ENOENT:
-                       printf ("ENOENT\n");
-               break;
-               case ENOMEM:
-                       printf ("ENOMEME\n");
-               break;
-       }
-       I3_PRINT_INFO1 (
-                               I3_INFO_LEVEL_WARNING,
-                               "Critical Error: Unable to bind i3 socket while 
creating context: %s.\n",
-                               strerror (errno)
-                               );
-       return NULL;
-               //panic("cl_init_context: bind\n");
-  }
-
-  I3_PRINT_DEBUG3(
-            I3_DEBUG_LEVEL_VERBOSE,
-            "Bound i3 fd=%d to %d : %s\n", 
-            ctx->fd, 
-            ctx->local.sin_port, 
-            inet_ntoa(ctx->local.sin_addr)
+    }
+
+    /* read the list of i3 server addreses from the configuration file */
+    read_srv_list(ctx);
+
+    /* create field descriptor and address data structure to
+     * receive i3 traffic */
+
+    {
+        int tmpFD = socket(AF_INET, SOCK_DGRAM, 0);
+        char *tmp;
+        if (tmpFD < 0) {
+            perror("socket");
+            I3_PRINT_DEBUG1( I3_DEBUG_LEVEL_WARNING,
+                             "Unable to open i3 UDP socket: %s.\n",
+                             strerror(errno)
+                             );
+            tmp = strerror(errno);
+
+            switch (errno) {
+            case EBADF:
+                printf("EBADF\n");
+                break;
+            case EINVAL:
+                printf("EINVAL\n");
+                break;
+            case EACCES:
+                printf("EACCES\n");
+                break;
+            case ENOTSOCK:
+                printf("ENOTSOCK\n");
+                break;
+            case EROFS:
+                printf("EROFS    \n");
+                break;
+
+            case EFAULT:
+                printf("EFAULT\n");
+                break;
+
+            case ENAMETOOLONG:
+                printf("ENAMETOOLONG\n");
+                break;
+            case ENOENT:
+                printf("ENOENT\n");
+                break;
+            case ENOMEM:
+                printf("ENOMEME\n");
+                break;
+            }
+            exit(-1);
+        } else {
+            ctx->fd = tmpFD;
+        }
+    }
+
+
+
+    memset(&ctx->local, 0, sizeof(struct sockaddr_in));
+    ctx->local.sin_family      = AF_INET;
+    ctx->local.sin_addr.s_addr = htonl(INADDR_ANY);
+    ctx->local.sin_port        = htons(local_port);
+
+    /* bind to the port */
+
+    if ((bind_ret_val = bind(ctx->fd, (struct sockaddr *) &ctx->local,  
sizeof(struct sockaddr_in))) < 0) {
+        switch (bind_ret_val) {
+        case EBADF:
+            printf("EBADF\n");
+            break;
+        case EINVAL:
+            printf("EINVAL\n");
+            break;
+        case EACCES:
+            printf("EACCES\n");
+            break;
+        case ENOTSOCK:
+            printf("ENOTSOCK\n");
+            break;
+        case EROFS:
+            printf("EROFS    \n");
+            break;
+
+        case EFAULT:
+            printf("EFAULT\n");
+            break;
+
+        case ENAMETOOLONG:
+            printf("ENAMETOOLONG\n");
+            break;
+        case ENOENT:
+            printf("ENOENT\n");
+            break;
+        case ENOMEM:
+            printf("ENOMEME\n");
+            break;
+        }
+        I3_PRINT_INFO1(
+            I3_INFO_LEVEL_WARNING,
+            "Critical Error: Unable to bind i3 socket while creating context: 
%s.\n",
+            strerror(errno)
+            );
+        return NULL;
+        //panic("cl_init_context: bind\n");
+    }
+
+    I3_PRINT_DEBUG3(
+        I3_DEBUG_LEVEL_VERBOSE,
+        "Bound i3 fd=%d to %d : %s\n",
+        ctx->fd,
+        ctx->local.sin_port,
+        inet_ntoa(ctx->local.sin_addr)
         );
 
 
-  if (local_ip_addr)
-    ctx->local_ip_addr = *local_ip_addr;
-  else
-    ctx->local_ip_addr = get_local_addr_cl(); // keep it in host format 
-
-  ctx->local_port = local_port;
-
-  /* PRIORITY QUEUE Initialization */
+    if (local_ip_addr) {
+        ctx->local_ip_addr = *local_ip_addr;
+    } else {
+        ctx->local_ip_addr = get_local_addr_cl(); // keep it in host format
+    }
+    ctx->local_port = local_port;
+
+    /* PRIORITY QUEUE Initialization */
 #define MAX_TRIGGERS 100000
 
-  /* precompute option part of headers */
-  for (opt_mask = 0; opt_mask < MAX_OPTS_MASK_SIZE; opt_mask++)
-    make_data_opt(ctx, opt_mask, &ctx->precomputed_opt[opt_mask]);
-
-  /* Ping list initialization */
-  ctx->list = NULL;
-
-  /* init timer heap */
-  init_timer_heap(ctx);
-
-  /* allocate data structure for file descriptors that the user may register */
-  ctx->i3fds = alloc_i3_fds();
-
-  return ctx;
+    /* precompute option part of headers */
+    for (opt_mask = 0; opt_mask < MAX_OPTS_MASK_SIZE; opt_mask++) {
+        make_data_opt(ctx, opt_mask, &ctx->precomputed_opt[opt_mask]);
+    }
+
+    /* Ping list initialization */
+    ctx->list = NULL;
+
+    /* init timer heap */
+    init_timer_heap(ctx);
+
+    /* allocate data structure for file descriptors that the user may register 
*/
+    ctx->i3fds = alloc_i3_fds();
+
+    return ctx;
 }
 
 /* close sockets and re-open them */
 void cl_reinit_context(cl_context *ctx)
 {
-  static int so_reuseaddr = 1;
-  uint8_t opt_mask;
-  
-  if (ctx->fd)
-    nw_close(ctx->fd);
-  if (ctx->init_tcp_ctx_flag && ctx->is_tcp)
-    close_tcp(ctx);
-
-  if ((ctx->fd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
-    perror ("socket recreation");
-    
-    exit(-1);
-  }
-
-  memset(&ctx->local, 0, sizeof(struct sockaddr_in));
-  ctx->local.sin_family = AF_INET;
-  ctx->local.sin_addr.s_addr = htonl(INADDR_ANY);
-  ctx->local.sin_port = htons(ctx->local_port);
-
-  if ((setsockopt(ctx->fd, SOL_SOCKET, SO_REUSEADDR,
-         (char *)&so_reuseaddr, sizeof(so_reuseaddr))) < 0) {
-    perror("setsockopt");
-  }
-  
-  if (bind(ctx->fd, (struct sockaddr *) &ctx->local, 
-          sizeof(struct sockaddr_in)) < 0) 
+    static int so_reuseaddr = 1;
+    uint8_t opt_mask;
+
+    if (ctx->fd) {
+        nw_close(ctx->fd);
+    }
+    if (ctx->init_tcp_ctx_flag && ctx->is_tcp) {
+        close_tcp(ctx);
+    }
+
+    if ((ctx->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        perror("socket recreation");
+
+        exit(-1);
+    }
+
+    memset(&ctx->local, 0, sizeof(struct sockaddr_in));
+    ctx->local.sin_family      = AF_INET;
+    ctx->local.sin_addr.s_addr = htonl(INADDR_ANY);
+    ctx->local.sin_port        = htons(ctx->local_port);
+
+    if ((setsockopt(ctx->fd, SOL_SOCKET, SO_REUSEADDR,
+                    (char *) &so_reuseaddr, sizeof(so_reuseaddr))) < 0) {
+        perror("setsockopt");
+    }
+
+    if (bind(ctx->fd, (struct sockaddr *) &ctx->local,
+             sizeof(struct sockaddr_in)) < 0) {
         I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "cl_reinit_context: bind\n");
-
-  /* precompute option part of headers */
-  for (opt_mask = 0; opt_mask < MAX_OPTS_MASK_SIZE; opt_mask++) {
-    if (ctx->precomputed_opt[opt_mask].p)
-      free(ctx->precomputed_opt[opt_mask].p);
-    make_data_opt(ctx, opt_mask, &ctx->precomputed_opt[opt_mask]);
-  }
-
-  if (ctx->is_tcp) {
-    init_tcp_ctx(ctx);
-    fprintf(stderr, "Warning: Mobility using TCP unsupported\n");  
-  }
+    }
+
+    /* precompute option part of headers */
+    for (opt_mask = 0; opt_mask < MAX_OPTS_MASK_SIZE; opt_mask++) {
+        if (ctx->precomputed_opt[opt_mask].p) {
+            free(ctx->precomputed_opt[opt_mask].p);
+        }
+        make_data_opt(ctx, opt_mask, &ctx->precomputed_opt[opt_mask]);
+    }
+
+    if (ctx->is_tcp) {
+        init_tcp_ctx(ctx);
+        fprintf(stderr, "Warning: Mobility using TCP unsupported\n");
+    }
 }
 
-
 void cl_destroy_context(cl_context *ctx)
 {
-  int i;
-  uint8_t opt_mask;
-
-  for (i = 0; i < CL_HTABLE_SIZE; i++) {
-    if (ctx->trigger_htable[i])
-      cl_free_trigger_list(ctx->trigger_htable[i]);
-    if (ctx->id_htable[i])
-      cl_free_id_list(ctx->id_htable[i]);
-  }
-
-  free_timer_heap(ctx);
-  free_i3_fds(ctx->i3fds);   
-  ctx->i3fds = NULL;
-
-  for (opt_mask = 0; opt_mask < MAX_OPTS_MASK_SIZE; opt_mask++)
-      if (ctx->precomputed_opt[opt_mask].p)
-         free(ctx->precomputed_opt[opt_mask].p);
-
-  free(ctx->s_array);
-
-  // close the connections assocatied with the context
-  nw_close (ctx->fd);
-  if (ctx->init_tcp_ctx_flag) {
-      close_tcp(ctx); 
-  }
-
-  free (ctx); //deallocate the memory
+    int i;
+    uint8_t opt_mask;
+
+    for (i = 0; i < CL_HTABLE_SIZE; i++) {
+        if (ctx->trigger_htable[i]) {
+            cl_free_trigger_list(ctx->trigger_htable[i]);
+        }
+        if (ctx->id_htable[i]) {
+            cl_free_id_list(ctx->id_htable[i]);
+        }
+    }
+
+    free_timer_heap(ctx);
+    free_i3_fds(ctx->i3fds);
+    ctx->i3fds = NULL;
+
+    for (opt_mask = 0; opt_mask < MAX_OPTS_MASK_SIZE; opt_mask++) {
+        if (ctx->precomputed_opt[opt_mask].p) {
+            free(ctx->precomputed_opt[opt_mask].p);
+        }
+    }
+
+    free(ctx->s_array);
+
+    // close the connections assocatied with the context
+    nw_close(ctx->fd);
+    if (ctx->init_tcp_ctx_flag) {
+        close_tcp(ctx);
+    }
+
+    free(ctx); //deallocate the memory
 }
 
 #define MAX_PACKET_SIZE 4096
 
-int cl_context_select(cl_context *ctx, int n, 
-                     fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 
-                     struct timeval *cl_to)
-{  
-  int                  max_fd, rc;
-  static struct timeval to, tv;
-  uint64_t              now, crt_time;
-  struct timeval       next_to, sel_to;
-  static cl_buf               *clb = NULL;
-  char                 packet_received;
-  assert(readfds);
-
-  /* initialize vars when this method is called for the first time */
-  if (NULL == clb) {
-    now = wall_time();
-    clb = cl_alloc_buf(MAX_PACKET_SIZE);
-    
-    /* set timeout to check whether the refresh has changed */
-    tv.tv_sec  = ADDR_CHECK_PERIOD;
-    tv.tv_usec = random_sec();
-    cl_set_timer(&tv, timeout_address_change, ctx);
-    
-    /* set timeout refresh the server list */
-    tv.tv_sec  = SERVER_UPDATE_PERIOD;
-    tv.tv_usec = random_sec();
-    cl_set_timer(&tv, timeout_server_update, ctx);
-  }
-  
-  /* There are three types of file descriptors:
-   *  1) Descriptors on which the client receives i3 packets from
-   *     the i3 servers (ctx->fd and ctx->fd_tcp)
-   *  2) Descriptors for which the application has registered callbacks
-   *  3) Descriptors which application has passed as arguments in 
-   *     the cl_select() function    
-   */
-  max_fd = MAX(ctx->fd + 1, n);
-  // printf("------------------ ctx->tcp_fd=%d, max_fd=%d\n", 
-  //    ctx->tcp_fd, max_fd);
-  if (ctx->is_tcp && ctx->init_tcp_ctx_flag) {
-    max_fd = MAX(ctx->tcp_fd + 1, max_fd);
-  }
-  max_fd = MAX(max_fd, ctx->i3fds->max_fd + 1);
-  
-  for (;;) {
-    /* update current time */
-    now = wall_time();
-    uint64_to_tval(&ctx->now, now);
-    
-    /* set socket descriptors for i3 traffic and for the callbacks
-     * inserted by the applications
-     */
-    /* if another tcp connection or user connection have been opened,
-     * update max_fd
-     */
-    if (ctx->is_tcp && ctx->init_tcp_ctx_flag && ctx->tcp_fd >= max_fd) {
-      max_fd = MAX(ctx->tcp_fd + 1, max_fd);
-    }
-    if (ctx->i3fds->max_fd >= max_fd) {
-      max_fd = MAX(max_fd, ctx->i3fds->max_fd + 1);
-    }
-
-    FD_SET(ctx->fd, readfds); 
-    
+int cl_context_select(cl_context *ctx, int n,
+                      fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+                      struct timeval *cl_to)
+{
+    int max_fd, rc;
+    static struct timeval to, tv;
+    uint64_t now, crt_time;
+    struct timeval next_to, sel_to;
+    static cl_buf *clb = NULL;
+    char packet_received;
+    assert(readfds);
+
+    /* initialize vars when this method is called for the first time */
+    if (NULL == clb) {
+        now        = wall_time();
+        clb        = cl_alloc_buf(MAX_PACKET_SIZE);
+
+        /* set timeout to check whether the refresh has changed */
+        tv.tv_sec  = ADDR_CHECK_PERIOD;
+        tv.tv_usec = random_sec();
+        cl_set_timer(&tv, timeout_address_change, ctx);
+
+        /* set timeout refresh the server list */
+        tv.tv_sec  = SERVER_UPDATE_PERIOD;
+        tv.tv_usec = random_sec();
+        cl_set_timer(&tv, timeout_server_update, ctx);
+    }
+
+    /* There are three types of file descriptors:
+     *  1) Descriptors on which the client receives i3 packets from
+     *     the i3 servers (ctx->fd and ctx->fd_tcp)
+     *  2) Descriptors for which the application has registered callbacks
+     *  3) Descriptors which application has passed as arguments in
+     *     the cl_select() function
+     */
+    max_fd = MAX(ctx->fd + 1, n);
+    // printf("------------------ ctx->tcp_fd=%d, max_fd=%d\n",
+    //     ctx->tcp_fd, max_fd);
     if (ctx->is_tcp && ctx->init_tcp_ctx_flag) {
-      FD_SET(ctx->tcp_fd, readfds);
-    }
-    
-    set_i3_fds(ctx->i3fds, readfds, writefds, exceptfds);
-    
-    /* invoke timer callbacks inserted by the application */
-    invoke_timers(ctx, now);
-
-    /* compute timeout (to) for select() as minimum between
-     * (1) the timeout (cl_to) pased by application are argument of 
-     *     cl_context_select() 
-     * (2) time to next event set by application via cl_set_timer()
-     *     system call
-     */
-    if (get_next_timer(ctx, &next_to, now)) {
-      tval_min(&to, &next_to, cl_to);
-    } else {
-      to = *cl_to;
-    }
-
-    /* remember timeout of select, because some slect implementations
-     * may update timeout "to" to indicate how much time has passed
-     */
-    sel_to = to;
-    packet_received = 0;
-    /* select() */
-    
-    if ((rc = select(max_fd, readfds, writefds, exceptfds, &to)) < 0) {
-      int err = nw_error();
-      if ((err == EINTR) || (err == EBADF)) {
-       if (cl_to) {
-         /* update cl_to with the time spent in select() */
-         crt_time = wall_time();
-         cl_update_to(cl_to, crt_time - now);
-         if (cl_to->tv_sec == 0 && cl_to->tv_usec == 0) {
-           /* check whether any timers expired while in select, before
-            * returning
-            */
-           invoke_timers(ctx, crt_time);
-           /* client's timout has expired; tell client to try again... */
-           errno = EINTR;
-           return rc;
-         }
-       }
-       /* check client's callbacks before continuing... */
-       invoke_i3_fds(ctx->i3fds, readfds, writefds, exceptfds);
-       continue;
-      } else {
-       err_sys("select_error\n");
-      }
-    }
-    
-    //printf("(3)\n");
-    if (rc > 0) {
-      /* at least one packet has been received, thus
-       * timeout "to" probably didn't expire 
-       */
-      packet_received = 1;
-    }
-    
-    /* check whether a packet hasn't been received on any of the 
-     * callback file descriptors
-     */
-    rc -= invoke_i3_fds(ctx->i3fds, readfds, writefds, exceptfds);
-    
-    /* i3 packet has been received */
-    if (FD_ISSET(ctx->fd, readfds) || 
-       (ctx->is_tcp && ctx->init_tcp_ctx_flag &&
-        FD_ISSET(ctx->tcp_fd, readfds))) {
-      int retVal;
-      
-      rc -= 1;
-
-      //ADDED_DILIP
-      retVal = cl_process_recd_i3_pkt(ctx, clb);
-      
-      if (retVal == CL_CONTINUE) {
-       if (cl_to)
-         /* update cl_to with the time spent in select */
-         cl_update_to(cl_to, wall_time() - now);
-       continue;
-      } 
-    }  
-    
-    /* either cl_to expired or a packet on another socket 
-     * has been received*/
-    /* --- WARNING: This can lead to EXTREMELY subtle bugs --- TODO! */
-    if (!packet_received && cl_to && tval_equal(cl_to, &sel_to)) {
-      /* if no packet has been received, then the select 
-       * timeout must have been expired. Check whether
-       * this timeout was equal to the client timeout, and if
-       * yes return 
-       */
-      cl_to->tv_sec = cl_to->tv_usec = 0;
-      invoke_timers(ctx, wall_time());
-      return rc;
-    }
-    
-    if (rc > 0) {
-      /* there is a packet received on a socket descriptor passed by the
-       * client in the cl_select function 
-       */
-      /* update cl_to with the time spent in select,
-       * and check whether any other timeouts expired during
-       * this period; then return
-       */      
-      crt_time = wall_time();
-      if (cl_to)
-       cl_update_to(cl_to, crt_time - now);
-      invoke_timers(ctx, crt_time);
-      return rc;
-    }
-    /* continue, after updating cl_to... */
-    if (cl_to)
-      cl_update_to(cl_to, wall_time() - now);
-  }
+        max_fd = MAX(ctx->tcp_fd + 1, max_fd);
+    }
+    max_fd = MAX(max_fd, ctx->i3fds->max_fd + 1);
+
+    for (;; ) {
+        /* update current time */
+        now = wall_time();
+        uint64_to_tval(&ctx->now, now);
+
+        /* set socket descriptors for i3 traffic and for the callbacks
+         * inserted by the applications
+         */
+        /* if another tcp connection or user connection have been opened,
+         * update max_fd
+         */
+        if (ctx->is_tcp && ctx->init_tcp_ctx_flag && ctx->tcp_fd >= max_fd) {
+            max_fd = MAX(ctx->tcp_fd + 1, max_fd);
+        }
+        if (ctx->i3fds->max_fd >= max_fd) {
+            max_fd = MAX(max_fd, ctx->i3fds->max_fd + 1);
+        }
+
+        FD_SET(ctx->fd, readfds);
+
+        if (ctx->is_tcp && ctx->init_tcp_ctx_flag) {
+            FD_SET(ctx->tcp_fd, readfds);
+        }
+
+        set_i3_fds(ctx->i3fds, readfds, writefds, exceptfds);
+
+        /* invoke timer callbacks inserted by the application */
+        invoke_timers(ctx, now);
+
+        /* compute timeout (to) for select() as minimum between
+         * (1) the timeout (cl_to) pased by application are argument of
+         *     cl_context_select()
+         * (2) time to next event set by application via cl_set_timer()
+         *     system call
+         */
+        if (get_next_timer(ctx, &next_to, now)) {
+            tval_min(&to, &next_to, cl_to);
+        } else {
+            to = *cl_to;
+        }
+
+        /* remember timeout of select, because some slect implementations
+         * may update timeout "to" to indicate how much time has passed
+         */
+        sel_to          = to;
+        packet_received = 0;
+        /* select() */
+
+        if ((rc = select(max_fd, readfds, writefds, exceptfds, &to)) < 0) {
+            int err = nw_error();
+            if ((err == EINTR) || (err == EBADF)) {
+                if (cl_to) {
+                    /* update cl_to with the time spent in select() */
+                    crt_time = wall_time();
+                    cl_update_to(cl_to, crt_time - now);
+                    if (cl_to->tv_sec == 0 && cl_to->tv_usec == 0) {
+                        /* check whether any timers expired while in select, 
before
+                         * returning
+                         */
+                        invoke_timers(ctx, crt_time);
+                        /* client's timout has expired; tell client to try 
again... */
+                        errno = EINTR;
+                        return rc;
+                    }
+                }
+                /* check client's callbacks before continuing... */
+                invoke_i3_fds(ctx->i3fds, readfds, writefds, exceptfds);
+                continue;
+            } else {
+                err_sys("select_error\n");
+            }
+        }
+
+        //printf("(3)\n");
+        if (rc > 0) {
+            /* at least one packet has been received, thus
+             * timeout "to" probably didn't expire
+             */
+            packet_received = 1;
+        }
+
+        /* check whether a packet hasn't been received on any of the
+         * callback file descriptors
+         */
+        rc -= invoke_i3_fds(ctx->i3fds, readfds, writefds, exceptfds);
+
+        /* i3 packet has been received */
+        if (FD_ISSET(ctx->fd, readfds) ||
+            (ctx->is_tcp && ctx->init_tcp_ctx_flag &&
+             FD_ISSET(ctx->tcp_fd, readfds))) {
+            int retVal;
+
+            rc    -= 1;
+
+            //ADDED_DILIP
+            retVal = cl_process_recd_i3_pkt(ctx, clb);
+
+            if (retVal == CL_CONTINUE) {
+                if (cl_to) {
+                    /* update cl_to with the time spent in select */
+                    cl_update_to(cl_to, wall_time() - now);
+                }
+                continue;
+            }
+        }
+
+        /* either cl_to expired or a packet on another socket
+         * has been received*/
+        /* --- WARNING: This can lead to EXTREMELY subtle bugs --- TODO! */
+        if (!packet_received && cl_to && tval_equal(cl_to, &sel_to)) {
+            /* if no packet has been received, then the select
+             * timeout must have been expired. Check whether
+             * this timeout was equal to the client timeout, and if
+             * yes return
+             */
+            cl_to->tv_sec = cl_to->tv_usec = 0;
+            invoke_timers(ctx, wall_time());
+            return rc;
+        }
+
+        if (rc > 0) {
+            /* there is a packet received on a socket descriptor passed by the
+             * client in the cl_select function
+             */
+            /* update cl_to with the time spent in select,
+             * and check whether any other timeouts expired during
+             * this period; then return
+             */
+            crt_time = wall_time();
+            if (cl_to) {
+                cl_update_to(cl_to, crt_time - now);
+            }
+            invoke_timers(ctx, crt_time);
+            return rc;
+        }
+        /* continue, after updating cl_to... */
+        if (cl_to) {
+            cl_update_to(cl_to, wall_time() - now);
+        }
+    }
 }
 
 /**
-  * This function is called when an i3 packet is received.
-  * The received i3 packet is processed here.  
-  * This function is usually called from within a select loop.
-  */
-int cl_process_recd_i3_pkt (cl_context * ctx, cl_buf *clb) {
-         
-  struct sockaddr_in fromaddr;
-  i3_header *hdr;
-  cl_trigger *ctr, *ctr_next;
-  
-  int recv_ret_val;
-  
-  /* hdr is allocated in cl_receive_packet; remember to free it ... */
-  recv_ret_val = cl_receive_packet_from (ctx, &hdr, clb, &fromaddr);
-  
-  if (recv_ret_val == 0) {
-    //Some error occurred while reading packet
-    
-    if (ctx->is_tcp)
-      close_tcp(ctx);
-    
-    return CL_RECV_ERROR;
-  }
-  
-  if (hdr == NULL)
-    return CL_CONTINUE;
-  
-  if (hdr->option_list) {
-    /* process option list received in the packet header */
-    cl_process_option_list (ctx, hdr, &fromaddr);
-  }
-  
-  if (hdr->stack && hdr->stack->len) {
-    
-    /* the packet may match multiple triggers;
-     * implement anycast, by getting the longest prefix match 
-     */
-    int max_prefix_len;
-    max_prefix_len =
-      cl_get_max_prefix_len_from_list(
-       ctx->trigger_htable[CL_HASH_TRIG(hdr->stack-> ids)], hdr->stack->ids);
-    
-    /* get trigger's data structure */
-    ctr = cl_get_trigger_by_id(
-      ctx->trigger_htable[CL_HASH_TRIG (hdr->stack->ids)],
-      hdr->stack->ids);
-
-    for (; ctr;) {
-      if ((does_id_match (&ctr->t->id,
-                         hdr->stack->ids,
-                         max_prefix_len) == FALSE)
-         || (ctr->t->to->type != I3_ADDR_TYPE_IPv4)) {
-       ctr = ctr->next;
-       continue;
-      }
-      
-      ctr_next = ctr->next;
-      
-      if (ctr->cbk_receive_packet.fun != NULL)
-       cl_trigger_callback (ctx, ctr, CL_CBK_RECEIVE_PACKET, hdr, clb);
-      else if (hdr->flags & I3_DATA)
-       cl_trigger_callback (ctx, ctr, CL_CBK_RECEIVE_PAYLOAD, NULL, clb);
-      else
-       printf
-         ("Invalid i3 packet type in cl_context_select()\n");
-      /* ctr pointer shouldn'be used after this call because the ctr
-       * might have been deleted in the callback 
-       */
-      
-      if (ctr_next)
-       ctr = cl_get_trigger_by_id (ctr_next, hdr->stack->ids);
-      else
-       break;
-    }
-  }
-  /* ... here we free the header */
-  free_i3_header (hdr);
-  
-  return CL_NO_CONTINUE;
+ * This function is called when an i3 packet is received.
+ * The received i3 packet is processed here.
+ * This function is usually called from within a select loop.
+ */
+int cl_process_recd_i3_pkt(cl_context *ctx, cl_buf *clb)
+{
+    struct sockaddr_in fromaddr;
+    i3_header *hdr;
+    cl_trigger *ctr, *ctr_next;
+
+    int recv_ret_val;
+
+    /* hdr is allocated in cl_receive_packet; remember to free it ... */
+    recv_ret_val = cl_receive_packet_from(ctx, &hdr, clb, &fromaddr);
+
+    if (recv_ret_val == 0) {
+        //Some error occurred while reading packet
+
+        if (ctx->is_tcp) {
+            close_tcp(ctx);
+        }
+
+        return CL_RECV_ERROR;
+    }
+
+    if (hdr == NULL) {
+        return CL_CONTINUE;
+    }
+
+    if (hdr->option_list) {
+        /* process option list received in the packet header */
+        cl_process_option_list(ctx, hdr, &fromaddr);
+    }
+
+    if (hdr->stack && hdr->stack->len) {
+        /* the packet may match multiple triggers;
+         * implement anycast, by getting the longest prefix match
+         */
+        int max_prefix_len;
+        max_prefix_len =
+            cl_get_max_prefix_len_from_list(
+                ctx->trigger_htable[CL_HASH_TRIG(hdr->stack->ids)], 
hdr->stack->ids);
+
+        /* get trigger's data structure */
+        ctr = cl_get_trigger_by_id(
+            ctx->trigger_htable[CL_HASH_TRIG(hdr->stack->ids)],
+            hdr->stack->ids);
+
+        for (; ctr; ) {
+            if ((does_id_match(&ctr->t->id,
+                               hdr->stack->ids,
+                               max_prefix_len) == FALSE)
+                || (ctr->t->to->type != I3_ADDR_TYPE_IPv4)) {
+                ctr = ctr->next;
+                continue;
+            }
+
+            ctr_next = ctr->next;
+
+            if (ctr->cbk_receive_packet.fun != NULL) {
+                cl_trigger_callback(ctx, ctr, CL_CBK_RECEIVE_PACKET, hdr, clb);
+            } else if (hdr->flags & I3_DATA) {
+                cl_trigger_callback(ctx, ctr, CL_CBK_RECEIVE_PAYLOAD, NULL, 
clb);
+            } else {
+                printf
+                    ("Invalid i3 packet type in cl_context_select()\n");
+            }
+            /* ctr pointer shouldn'be used after this call because the ctr
+             * might have been deleted in the callback
+             */
+
+            if (ctr_next) {
+                ctr = cl_get_trigger_by_id(ctr_next, hdr->stack->ids);
+            } else {
+                break;
+            }
+        }
+    }
+    /* ... here we free the header */
+    free_i3_header(hdr);
+
+    return CL_NO_CONTINUE;
 }
 
-
-
 int get_i3_server(int num_servers, srv_address *s_array)
 {
-  int num = 0;
-  int i;
-
-  //printf("In get_i3_server, num_servers = %d\n\n", num_servers);
-  
-  if (num_servers == 0)
-      return -1;
-
-  for (i = 0; i < 2 * num_servers; i++) {
-    num = n_rand(num_servers);
-    if (s_array[num].status == ID_UP)
-      return num;
-  }
-
-  num = 0;
-  for (i = 0; i < num_servers; i++) {
-    if (s_array[i].status == ID_UP)
-      return i;
-    if (s_array[i].status == ID_DOWN)
-      num++;
-  }
-  /* there are known servers in the list, but all of them are down;
-   * select a random one */
-  if (num) {
-    num = n_rand(num);
+    int num = 0;
+    int i;
+
+    //printf("In get_i3_server, num_servers = %d\n\n", num_servers);
+
+    if (num_servers == 0) {
+        return -1;
+    }
+
+    for (i = 0; i < 2 * num_servers; i++) {
+        num = n_rand(num_servers);
+        if (s_array[num].status == ID_UP) {
+            return num;
+        }
+    }
+
+    num = 0;
     for (i = 0; i < num_servers; i++) {
-      if (s_array[i].status == ID_DOWN) {
-       if (num == 0)
-         return i;
-       else
-         num--;
-      }
-    }
-  }
+        if (s_array[i].status == ID_UP) {
+            return i;
+        }
+        if (s_array[i].status == ID_DOWN) {
+            num++;
+        }
+    }
+    /* there are known servers in the list, but all of them are down;
+     * select a random one */
+    if (num) {
+        num = n_rand(num);
+        for (i = 0; i < num_servers; i++) {
+            if (s_array[i].status == ID_DOWN) {
+                if (num == 0) {
+                    return i;
+                } else {
+                    num--;
+                }
+            }
+        }
+    }
 
-  panic("Likely bug in get_i3_server\n");
-  return -1;
+    panic("Likely bug in get_i3_server\n");
+    return -1;
 }
 
-
-srv_address *set_i3_server_status(srv_address *s_array, 
-                                 uint32_t ip_addr, uint16_t port,
-                                 int status)
+srv_address *set_i3_server_status(srv_address *s_array,
+                                  uint32_t ip_addr, uint16_t port,
+                                  int status)
 {
-  int i;
+    int i;
 
-  for (i = 0; i < MAX_NUM_SRV; i++) {
-    if ((s_array[i].port == port) &&
-       (s_array[i].addr.s_addr == ip_addr)) {
-      s_array[i].status = status;
-      return &s_array[i];
+    for (i = 0; i < MAX_NUM_SRV; i++) {
+        if ((s_array[i].port == port) &&
+            (s_array[i].addr.s_addr == ip_addr)) {
+            s_array[i].status = status;
+            return &s_array[i];
+        }
     }
-  }
 
-  return NULL;
+    return NULL;
 }
 
-
-
 /* read the list of server addresses and their port numbers
  * from the configuration files */
 void read_srv_list(cl_context *ctx)
 {
-  int  i = 0, port, ret;
-  char addrstr[MAX_BUF_SIZE];
-  char idstr[MAX_BUF_SIZE];
-  char** addrs = read_i3server_list(&ctx->num_servers);
-
-  for (i = 0; i < ctx->num_servers; i++)
-  {
-    ret = sscanf(addrs[i], "%s %d %s\n", addrstr, &port, idstr);
-    free(addrs[i]);
-
-    I3_PRINT_DEBUG2(I3_DEBUG_LEVEL_VERBOSE,"Using i3 server at %s 
%d\n",addrstr,port);
-
-    if (i >= MAX_NUM_SRV)
-      continue;
-
-    if (ret >= 3)
-       ctx->s_array[i].id = atoi3id(idstr);
-    else
-       fprintf(stderr, "Warning: proxy configuration file has incomplete 
<addr> field\n");
-    ctx->s_array[i].port = port;
+    int i        = 0, port, ret;
+    char addrstr[MAX_BUF_SIZE];
+    char idstr[MAX_BUF_SIZE];
+    char **addrs = read_i3server_list(&ctx->num_servers);
+
+    for (i = 0; i < ctx->num_servers; i++) {
+        ret = sscanf(addrs[i], "%s %d %s\n", addrstr, &port, idstr);
+        free(addrs[i]);
+
+        I3_PRINT_DEBUG2(I3_DEBUG_LEVEL_VERBOSE, "Using i3 server at %s %d\n", 
addrstr, port);
+
+        if (i >= MAX_NUM_SRV) {
+            continue;
+        }
+
+        if (ret >= 3) {
+            ctx->s_array[i].id = atoi3id(idstr);
+        } else {
+            fprintf(stderr, "Warning: proxy configuration file has incomplete 
<addr> field\n");
+        }
+        ctx->s_array[i].port = port;
 //#ifdef _WIN32
 //    if (inet_aton(addrstr, &ctx->s_array[i].addr) < 0)
 //#else
-    if (inet_pton(AF_INET, addrstr, &ctx->s_array[i].addr) < 0)
+        if (inet_pton(AF_INET, addrstr, &ctx->s_array[i].addr) < 0) {
 //#endif
-           I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "client_init: inet_pton 
error\n");
-
-    /* inet_pton returns the address in network format;
-     * convert it in host format */
-    ctx->s_array[i].addr.s_addr = ntohl(ctx->s_array[i].addr.s_addr);
-    ctx->s_array[i].status = ID_DOWN;
-
-  }
-
-  free(addrs);
-
-  printf("Number of i3 servers = %d\n", ctx->num_servers);
+            I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "client_init: inet_pton 
error\n");
+        }
+
+        /* inet_pton returns the address in network format;
+         * convert it in host format */
+        ctx->s_array[i].addr.s_addr = ntohl(ctx->s_array[i].addr.s_addr);
+        ctx->s_array[i].status      = ID_DOWN;
+    }
+
+    free(addrs);
+
+    printf("Number of i3 servers = %d\n", ctx->num_servers);
 }
 
 void update_srv_list(cl_context *ctx)
 {
-  int i, k = MAX_NUM_SRV;
-  uint16_t port[MAX_NUM_SRV];
-  uint32_t addr[MAX_NUM_SRV];
-  uint64_t rtt[MAX_NUM_SRV];
-  
-  if (cl_ctx_get_top_k_servers(ctx, &k, addr, port, rtt) == CL_RET_OK) {
-    for (i = 0; i < k; i++) {
-           //printf("in update_srv_list i=%d port[i] = %d \n", i, port[i]);
-      ctx->s_array[i].addr.s_addr = addr[i];
-      ctx->s_array[i].port = port[i];
-      ctx->s_array[i].status = ID_UP;  //ADDED by dilip
+    int i, k = MAX_NUM_SRV;
+    uint16_t port[MAX_NUM_SRV];
+    uint32_t addr[MAX_NUM_SRV];
+    uint64_t rtt[MAX_NUM_SRV];
+
+    if (cl_ctx_get_top_k_servers(ctx, &k, addr, port, rtt) == CL_RET_OK) {
+        for (i = 0; i < k; i++) {
+            //printf("in update_srv_list i=%d port[i] = %d \n", i, port[i]);
+            ctx->s_array[i].addr.s_addr = addr[i];
+            ctx->s_array[i].port        = port[i];
+            ctx->s_array[i].status      = ID_UP; //ADDED by dilip
+        }
+        if (k > 0) {
+            ctx->num_servers = k;
+        }
     }
-    if (k > 0)
-      ctx->num_servers = k;
-  }
 }
-  
 
 /* function used to process timeval data structures */
 int tval_zero(struct timeval *t)
 {
-  if (t->tv_sec || t->tv_usec)
-    return FALSE;
-  else
-    return TRUE;
+    if (t->tv_sec || t->tv_usec) {
+        return FALSE;
+    } else {
+        return TRUE;
+    }
 }
 
 void tval_min(struct timeval *tmin, struct timeval *t1, struct timeval *t2)
 {
-  if (!t1)
-    *tmin = *t2;
-  else if (!t2)
-    *tmin = *t1;
-  else {
-    tval_normalize(t1);
-    tval_normalize(t2);
+    if (!t1) {
+        *tmin = *t2;
+    } else if (!t2) {
+        *tmin = *t1;
+    } else {
+        tval_normalize(t1);
+        tval_normalize(t2);
 
-    if (t1->tv_sec < t2->tv_sec)
-      *tmin = *t1;
-    else if (t1->tv_sec > t2->tv_sec)
-      *tmin = *t2;
-    else if (t1->tv_usec < t2->tv_usec)
-      *tmin = *t1;
-    else
-      *tmin = *t2;
-  }
+        if (t1->tv_sec < t2->tv_sec) {
+            *tmin = *t1;
+        } else if (t1->tv_sec > t2->tv_sec) {
+            *tmin = *t2;
+        } else if (t1->tv_usec < t2->tv_usec) {
+            *tmin = *t1;
+        } else {
+            *tmin = *t2;
+        }
+    }
 }
 
-void cl_update_to(struct timeval *cl_to, uint64_t diff) 
+void cl_update_to(struct timeval *cl_to, uint64_t diff)
 {
-  diff = tval_to_uint64(cl_to) - diff;
-  if ((int64_t)diff < 0) {
-    diff = 0;
-  }
-  uint64_to_tval(cl_to, diff); 
+    diff = tval_to_uint64(cl_to) - diff;
+    if ((int64_t) diff < 0) {
+        diff = 0;
+    }
+    uint64_to_tval(cl_to, diff);
 }
 
-
 int tval_equal(struct timeval *t1, struct timeval *t2)
 {
-  if (t1->tv_sec == t2->tv_sec && t1->tv_usec == t2->tv_usec)
-    return TRUE;
-  else
-    return FALSE;
+    if (t1->tv_sec == t2->tv_sec && t1->tv_usec == t2->tv_usec) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
 }
-      
 
 uint64_t tval_to_uint64(struct timeval *tv)
 {
-  return tv->tv_sec*UMILLION + tv->tv_usec;
+    return tv->tv_sec * UMILLION + tv->tv_usec;
 }
 
-
 void uint64_to_tval(struct timeval *tv, uint64_t time)
 {
-  tv->tv_sec = time/UMILLION;
-  tv->tv_usec = time % UMILLION;
+    tv->tv_sec  = time / UMILLION;
+    tv->tv_usec = time % UMILLION;
 }
 
-
 void tval_normalize(struct timeval *t)
 {
-  if (t->tv_usec >= UMILLION) {
-    t->tv_sec += t->tv_usec/UMILLION;
-    t->tv_usec = t->tv_usec % UMILLION;
-  }
+    if (t->tv_usec >= UMILLION) {
+        t->tv_sec += t->tv_usec / UMILLION;
+        t->tv_usec = t->tv_usec % UMILLION;
+    }
 }
 
-
-/* get local address -- use fn in utils/ */  
+/* get local address -- use fn in utils/ */
 struct in_addr get_local_addr_cl()
 {
-  struct in_addr ia;
-  ia.s_addr = ntohl(get_local_addr());
-  return ia;
+    struct in_addr ia;
+    ia.s_addr = ntohl(get_local_addr());
+    return ia;
 }
 
 int check_addr_change(struct in_addr *ia)
 {
-  struct in_addr newAddr;
-
-  newAddr.s_addr = ntohl(get_local_addr());
-
-  if (ia->s_addr != newAddr.s_addr) {
-    ia->s_addr = newAddr.s_addr;
-    return 1;
-  } else {
-    return 0;
-  }
+    struct in_addr newAddr;
+
+    newAddr.s_addr = ntohl(get_local_addr());
+
+    if (ia->s_addr != newAddr.s_addr) {
+        ia->s_addr = newAddr.s_addr;
+        return 1;
+    } else {
+        return 0;
+    }
 }
 
 void timeout_address_change(void *context)
 {
-  struct timeval tv;
-  cl_context *ctx = (cl_context *) context;
-
-  if (check_addr_change(&(ctx->local_ip_addr))) {
-    struct in_addr temp;
-    temp.s_addr = htonl(ctx->local_ip_addr.s_addr);
-    fprintf(stderr, "Detected address change to %s: updating triggers\n",
-           inet_ntoa(temp));
-    cl_reinit_context(ctx);
-    cl_update_triggers(ctx);
-    
-    // inform ping process
-    set_status(ctx->ping_start_time, wall_time());
-  }
-  tv.tv_sec  = ADDR_CHECK_PERIOD;
-  tv.tv_usec = random_sec();
-  cl_set_timer(&tv, timeout_address_change, ctx);
+    struct timeval tv;
+    cl_context *ctx = (cl_context *) context;
+
+    if (check_addr_change(&(ctx->local_ip_addr))) {
+        struct in_addr temp;
+        temp.s_addr = htonl(ctx->local_ip_addr.s_addr);
+        fprintf(stderr, "Detected address change to %s: updating triggers\n",
+                inet_ntoa(temp));
+        cl_reinit_context(ctx);
+        cl_update_triggers(ctx);
+
+        // inform ping process
+        set_status(ctx->ping_start_time, wall_time());
+    }
+    tv.tv_sec  = ADDR_CHECK_PERIOD;
+    tv.tv_usec = random_sec();
+    cl_set_timer(&tv, timeout_address_change, ctx);
 }
 
 void timeout_server_update(void *context)
@@ -899,13 +915,12 @@
     tv.tv_sec  = SERVER_UPDATE_PERIOD;
     tv.tv_usec = random_sec();
     cl_set_timer(&tv, timeout_server_update, ctx);
-    
+
     // If TCP socket had not been previous initialized, try again.
-    if ( ctx->is_tcp && ! ctx->init_tcp_ctx_flag) {
+    if (ctx->is_tcp && !ctx->init_tcp_ctx_flag) {
         I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_VERBOSE,
-                "Retrying TCP socket initialization\n"
-                );
+                        "Retrying TCP socket initialization\n"
+                        );
         init_tcp_ctx(ctx);
     }
 }
-

=== modified file 'i3/i3_client/i3_client_context.h'
--- i3/i3_client/i3_client_context.h    2010-01-12 12:35:31 +0000
+++ i3/i3_client/i3_client_context.h    2010-02-11 11:49:47 +0000
@@ -1,9 +1,9 @@
 /***************************************************************************
-                          i3_client_context.h  -  description
-                             -------------------
-    begin                :  Aug 14 2003
-    email                : istoica@xxxxxxxxxxxxxxx
- ***************************************************************************/
+*                         i3_client_context.h  -  description
+*                            -------------------
+*   begin                :  Aug 14 2003
+*   email                : istoica@xxxxxxxxxxxxxxx
+***************************************************************************/
 
 #ifndef I3_CLIENT_CONTEXT_H
 #define I3_CLIENT_CONTEXT_H
@@ -15,24 +15,23 @@
 #define CL_RECV_ERROR -100
 
 cl_context *cl_create_context(struct in_addr *ip_addr,
-                             uint16_t local_port
-                             );
+                              uint16_t local_port);
 void cl_destroy_context(cl_context *ctx);
 
-void init_tcp_ctx(cl_context* ctx);
+void init_tcp_ctx(cl_context *ctx);
 
-int cl_context_select(cl_context *ctx, int n, 
-                     fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 
-                     struct timeval *cl_to);
+int cl_context_select(cl_context *ctx, int n,
+                      fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+                      struct timeval *cl_to);
 
 void read_srv_list(cl_context *ctx);
 void update_srv_list(cl_context *ctx);
-srv_address *set_i3_server_status(srv_address *s_array, 
-                                 uint32_t ip_addr, uint16_t port,
-                                 int status);
+srv_address *set_i3_server_status(srv_address *s_array,
+                                  uint32_t ip_addr, uint16_t port,
+                                  int status);
 int get_i3_server(int num_servers, srv_address *s_array);
 
-int cl_process_recd_i3_pkt(cl_context*, cl_buf*);
+int cl_process_recd_i3_pkt(cl_context *, cl_buf *);
 
 void timeout_address_change(void *ctx);
 void timeout_server_update(void *ctx);

=== modified file 'i3/i3_client/i3_client_fd.c'
--- i3/i3_client/i3_client_fd.c 2010-01-06 22:17:32 +0000
+++ i3/i3_client/i3_client_fd.c 2010-02-11 11:49:47 +0000
@@ -1,14 +1,14 @@
 /***************************************************************************
-                          i3_client_fd.c  -  description
-                             -------------------
-    begin                :  July 22 2004
-    email                : istoica@xxxxxxxxxxxxxxx
-
-    This file contains functions to manipulate a list of file descriptors.
-    This list contains file descriptors for which the application has inserted
-    a callback CL_CBK_READ_FD. 
-
- ***************************************************************************/
+*                         i3_client_fd.c  -  description
+*                            -------------------
+*   begin                :  July 22 2004
+*   email                : istoica@xxxxxxxxxxxxxxx
+*
+*   This file contains functions to manipulate a list of file descriptors.
+*   This list contains file descriptors for which the application has inserted
+*   a callback CL_CBK_READ_FD.
+*
+***************************************************************************/
 
 #include <stdlib.h>
 #include <sys/types.h>
@@ -21,174 +21,174 @@
 
 i3_fds *alloc_i3_fds(void)
 {
-  i3_fds *n;
+    i3_fds *n;
 
-  if ((n = (i3_fds *)calloc(1, sizeof(i3_fds))) != NULL) {
-    return n;
-  }
-  I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "alloc_i3_fds: memory allocation 
error.\n");
-  return NULL;
+    if ((n = (i3_fds *) calloc(1, sizeof(i3_fds))) != NULL) {
+        return n;
+    }
+    I3_PRINT_DEBUG0(I3_DEBUG_LEVEL_MINIMAL, "alloc_i3_fds: memory allocation 
error.\n");
+    return NULL;
 }
 
 void free_i3_fds(i3_fds *fds)
 {
-  free_fd_list(fds->readfd_list);
-  free_fd_list(fds->writefd_list);
-  free_fd_list(fds->exceptfd_list);
-  free(fds);
-}
-
-
-int invoke_i3_fds(i3_fds *fds, 
-                 fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
-{
-  int fd_cnt;
-
-  fd_cnt = invoke_fd_callbacks(fds->readfd_list, readfds);
-  fd_cnt += invoke_fd_callbacks(fds->writefd_list, writefds);
-  fd_cnt += invoke_fd_callbacks(fds->exceptfd_list, exceptfds);
-
-  return fd_cnt;
-}
-
-void set_i3_fds(i3_fds *fds, 
-               fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
-{
-  fd_set_list(fds->readfd_list, readfds);
-  fd_set_list(fds->writefd_list, writefds);
-  fd_set_list(fds->exceptfd_list, exceptfds);
-}
-
-void compute_max_i3_fds(i3_fds *fds) 
-{
-  fds->max_fd =  max_fd_list(fds->readfd_list);
-  fds->max_fd =  MAX(fds->max_fd, max_fd_list(fds->writefd_list));
-  fds->max_fd =  MAX(fds->max_fd, max_fd_list(fds->exceptfd_list));
-}
-
+    free_fd_list(fds->readfd_list);
+    free_fd_list(fds->writefd_list);
+    free_fd_list(fds->exceptfd_list);
+    free(fds);
+}
+
+int invoke_i3_fds(i3_fds *fds,
+                  fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
+{
+    int fd_cnt;
+
+    fd_cnt  = invoke_fd_callbacks(fds->readfd_list, readfds);
+    fd_cnt += invoke_fd_callbacks(fds->writefd_list, writefds);
+    fd_cnt += invoke_fd_callbacks(fds->exceptfd_list, exceptfds);
+
+    return fd_cnt;
+}
+
+void set_i3_fds(i3_fds *fds,
+                fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
+{
+    fd_set_list(fds->readfd_list, readfds);
+    fd_set_list(fds->writefd_list, writefds);
+    fd_set_list(fds->exceptfd_list, exceptfds);
+}
+
+void compute_max_i3_fds(i3_fds *fds)
+{
+    fds->max_fd =  max_fd_list(fds->readfd_list);
+    fds->max_fd =  MAX(fds->max_fd, max_fd_list(fds->writefd_list));
+    fds->max_fd =  MAX(fds->max_fd, max_fd_list(fds->exceptfd_list));
+}
 
 fd_node *alloc_fd_node(int fd, void (*fun)(int, void *), void *params)
 {
-  fd_node *n;
+    fd_node *n;
 
-  if ((n = (fd_node *)calloc(1, sizeof(f