[chord] no auth patch

Michael Walfish mwalfish at lcs.mit.edu
Fri Jul 25 08:09:44 EDT 2003


attached. much of the code in the previous patch is unnecessary since
there is not a need to distinguish two different block types that each
address public keys.

this patch:
a) renames a variable in dhash/server.C to make it a bit more explicit
b) removes a tiny bit of dead code
c) factors out what is done when a DB is opened
d) exposes noauth via the dhashclient

it patches against HEAD with patch level -p1:

% cp patch-name sfsnet-dir/
% cd sfsnet-dir
% patch -Np1 < patch-name

If I ought to directly commit these changes, please let me know. I'm happy
to do that.
-------------- next part --------------
diff -ru chord-src-head/devel/test_types.C chord-src-noauth/devel/test_types.C
--- chord-src-head/devel/test_types.C	2003-07-24 01:46:21.000000000 -0400
+++ chord-src-noauth/devel/test_types.C	2003-07-25 04:34:56.000000000 -0400
@@ -41,7 +41,11 @@
 			     ptr<insert_info> i);
 void fetch_cb_append_second (dhashclient dhash, dhash_stat stat, ptr<dhash_block> blk, vec<chordID> path);
 
-void fetch_cb (dhash_stat stat, ptr<dhash_block> blk, vec<chordID> path);
+void fetch_cb (dhashclient dhash, int btype, dhash_stat stat, 
+	       ptr<dhash_block> blk, vec<chordID> path);
+void nonexistent_fetch_cb (dhash_stat stat, ptr<dhash_block> blk, 
+			   vec<chordID> path);
+dhash_ctype magic2ctype(int btype);
 void store_cb_ch2 (dhashclient dhash, chordID pred, 
 		   dhash_stat status, ptr<insert_info> i);
 char *data_one = "This is some test data";
@@ -79,7 +83,9 @@
     options = NULL;
   }
 
-  dhash.retrieve (i->key, DHASH_CONTENTHASH, wrap (&fetch_cb), options);
+  dhash.retrieve (i->key, DHASH_CONTENTHASH, 
+		  wrap (&fetch_cb, dhash, CONTENT_HASH), 
+	          options);
 }
 
 
@@ -102,7 +108,9 @@
   options->flags = DHASHCLIENT_GUESS_SUPPLIED;
   warn << "2 pred " << pred << "\n";
   options->guess = pred;
-  dhash.retrieve (i->key, DHASH_CONTENTHASH, wrap (&fetch_cb), options);
+  dhash.retrieve (i->key, DHASH_CONTENTHASH, 
+	          wrap (&fetch_cb, dhash, CONTENT_HASH), 
+	          options);
 }
 
 void
@@ -113,7 +121,8 @@
   else
     warn << "pk store successful\n";
 
-  dhash.retrieve (i->key, DHASH_KEYHASH, wrap (&fetch_cb));
+  dhash.retrieve (i->key, DHASH_KEYHASH, 
+		  wrap (&fetch_cb, dhash, PUB_KEY));
 }
 
 void
@@ -124,7 +133,8 @@
   else
     warn << "noauth store successful " << i->key << "\n";
 
-  dhash.retrieve (i->key, DHASH_NOAUTH, wrap (&fetch_cb));
+  dhash.retrieve (i->key, DHASH_NOAUTH, 
+	          wrap (&fetch_cb, dhash, NOAUTH));
 }
 
 void
@@ -169,7 +179,8 @@
 }
 
 void
-fetch_cb (dhash_stat stat, ptr<dhash_block> blk, vec<chordID> path)
+fetch_cb (dhashclient dhash, int btype, dhash_stat stat, 
+	  ptr<dhash_block> blk, vec<chordID> path)
 {
 
   if (!blk) {
@@ -183,10 +194,39 @@
       warnx << path[i] << " ";
     warnx << "\n";
   }
-  
-  exit (0);
+
+  // assumption is that no block has ChordID 0.
+  bigint n = 0;
+
+  // end the test sooner rather than later
+  ptr<option_block> ob = New refcounted<option_block>;
+  ob->flags = DHASHCLIENT_NO_RETRY_ON_LOOKUP;
+
+  dhash.retrieve (n, magic2ctype(btype), wrap (&nonexistent_fetch_cb), ob);
+}
+
+void
+nonexistent_fetch_cb (dhash_stat stat, ptr<dhash_block> blk, vec<chordID> path)
+{
+    if (blk) 
+	warn << "Error (unless you have a block with chordID = 0)\n";
+    else
+	warn << "Successfully returned blk == NULL on non-existent block\n";
+
+    exit(0);
 }
 
+dhash_ctype
+magic2ctype(int btype)
+{
+    if (btype == CONTENT_HASH) return DHASH_CONTENTHASH;
+    if (btype == PUB_KEY     ) return DHASH_KEYHASH;
+    if (btype == APPEND      ) return DHASH_APPEND;
+    if (btype == NOAUTH      ) return DHASH_NOAUTH;
+
+    assert(false);
+    return DHASH_UNKNOWN;
+}
 
 void
 usage (char *progname) 
@@ -251,6 +291,9 @@
     usage (argv[0]);
     break;
   }
-	  
+	 
   amain ();
 }
+
+
+
diff -ru chord-src-head/dhash/client.C chord-src-noauth/dhash/client.C
--- chord-src-head/dhash/client.C	2003-07-24 22:39:27.000000000 -0400
+++ chord-src-noauth/dhash/client.C	2003-07-25 04:34:56.000000000 -0400
@@ -577,8 +577,6 @@
       ((char *)NULL, frag.len (), DHASH_CONTENTHASH);
     bcopy (frag.cstr (), blk->data, frag.len ());
     
-    bigint h = compute_hash (blk->data, blk->len);
-
     // Count up for each RPC that will be dispatched
     ss->out += 1;
 
diff -ru chord-src-head/dhash/dhashclient.C chord-src-noauth/dhash/dhashclient.C
--- chord-src-head/dhash/dhashclient.C	2003-07-25 04:24:11.000000000 -0400
+++ chord-src-noauth/dhash/dhashclient.C	2003-07-25 04:47:37.000000000 -0400
@@ -82,7 +82,7 @@
       
       int m_len = x.uio ()->resid ();
       char *m_dat = suio_flatten (x.uio ());
-      insert (to, m_dat, m_len, cb, DHASH_APPEND, buflen, NULL);
+      insert_togateway (to, m_dat, m_len, cb, DHASH_APPEND, buflen, NULL);
       xfree (m_dat);
     } else {
       (*cb) (DHASH_ERR, NULL); // marshalling failed.
@@ -100,9 +100,9 @@
  * key = HASH (data)
  */
 void
-dhashclient::insert (bigint key, const char *buf,
-                     size_t buflen, cbinsertgw_t cb, 
-		     ptr<option_block> options)
+dhashclient::insert_worker_nopk (bigint key, const char *buf,
+                                 size_t buflen, cbinsertgw_t cb, 
+                                 dhash_ctype t, ptr<option_block> options)
 {
   xdrsuio x;
   int size = buflen + 3 & ~3;
@@ -113,7 +113,7 @@
       
       int m_len = x.uio ()->resid ();
       char *m_dat = suio_flatten (x.uio ());
-      insert (key, m_dat, m_len, cb, DHASH_CONTENTHASH, buflen, options);
+      insert_togateway (key, m_dat, m_len, cb, t, buflen, options);
       xfree (m_dat);
     } else {
       (*cb) (DHASH_ERR, NULL); // marshalling failed.
@@ -121,6 +121,14 @@
 }
 
 void
+dhashclient::insert (bigint key, const char *buf,
+                     size_t buflen, cbinsertgw_t cb, 
+		     ptr<option_block> options)
+{
+  insert_worker_nopk (key, buf, buflen, cb, DHASH_CONTENTHASH, options);
+}
+
+void
 dhashclient::insert (const char *buf, size_t buflen, cbinsertgw_t cb,
                      ptr<option_block> options)
 {
@@ -128,6 +136,13 @@
   insert (key, buf, buflen, cb, options);
 }
 
+void
+dhashclient::insert_noauth (bigint key, const char *buf,
+                            size_t buflen, cbinsertgw_t cb,
+                            ptr<option_block> options)
+{
+    insert_worker_nopk (key, buf, buflen, cb, DHASH_NOAUTH, options);
+}
 
 /* 
  * keyhash block convention:
@@ -160,7 +175,8 @@
 
   int m_len = x.uio ()->resid ();
   char *m_dat = suio_flatten (x.uio ());
-  insert (hash, m_dat, m_len, cb, DHASH_KEYHASH, x.uio()->resid(), options);
+  insert_togateway (hash, m_dat, m_len, cb, DHASH_KEYHASH, 
+                    x.uio()->resid(), options);
   xfree (m_dat);
 }
 
@@ -169,10 +185,10 @@
  * generic insert (called by above methods)
  */
 void
-dhashclient::insert (bigint key, const char *buf, 
-		     size_t buflen, cbinsertgw_t cb,
-		     dhash_ctype t, size_t realsize,
-		     ptr<option_block> options)
+dhashclient::insert_togateway (bigint key, const char *buf, 
+                               size_t buflen, cbinsertgw_t cb,
+                               dhash_ctype t, size_t realsize,
+                               ptr<option_block> options)
 {
   dhash_insert_arg arg;
   arg.blockID = key;
@@ -204,12 +220,12 @@
   ptr<insert_info> i = New refcounted<insert_info>(key, r);
   if (err) {
     errstr = strbuf () << "rpc error " << err;
-    warn << "dhashclient::insert failed: " << key << ": " << errstr << "\n";
+    warn << "dhashclient::insert failed (1): " << key << ": " << errstr << "\n";
     (*cb) (DHASH_RPCERR, i); //RPC failure
   } else {
     if (res->status != DHASH_OK) {
       errstr = dhasherr2str (res->status);
-      warn << "dhashclient::insert failed: " << key << ": " << errstr << "\n";
+      warn << "dhashclient::insert failed (2): " << key << ": " << errstr << "\n";
     }
     else {
       i->path.setsize (res->resok->path.size ());
@@ -254,6 +270,7 @@
 			 clnt_stat err)
 {
   str errstr;
+  bool verify_failed = false;
   if (err)
     errstr = strbuf () << "rpc error " << err;
   else if (res->status != DHASH_OK)
@@ -263,20 +280,27 @@
 		      res->resok->len)) {
       errstr = strbuf () << "data did not verify. len: " << res->resok->len
 	                 << " ctype " << res->resok->ctype;
+      verify_failed = true;
     } else {
       // success
       ptr<dhash_block> blk = get_block_contents (res->resok->block.base(), 
 						 res->resok->block.size(), 
 						 res->resok->ctype);
+      vec<chordID> path;
+      for (u_int i = 0; i < res->resok->path.size (); i++)
+	path.push_back (res->resok->path[i]);
+  
+      if (!blk) {
+        (*cb) (DHASH_RETRIEVE_NOVERIFY, NULL, path);
+        return;
+      }
+
       blk->hops = res->resok->hops;
       blk->errors = res->resok->errors;
       blk->retries = res->resok->retries;
       for (u_int i = 0; i < res->resok->times.size (); i++)
 	blk->times.push_back (res->resok->times[i]);
       
-      vec<chordID> path;
-      for (u_int i = 0; i < res->resok->path.size (); i++)
-	path.push_back (res->resok->path[i]);
       (*cb) (DHASH_OK, blk, path);
       return;
     } 
@@ -284,6 +308,8 @@
 
   warn << "dhashclient::retrieve failed: " << key << ": " << errstr << "\n";
   vec<chordID> e_path;
-  (*cb) (res->status, NULL, e_path); // failure
+  // failure
+  (*cb) (verify_failed ? DHASH_RETRIEVE_NOVERIFY : res->status, NULL, e_path); 
 }
 
+
diff -ru chord-src-head/dhash/dhashclient.h chord-src-noauth/dhash/dhashclient.h
--- chord-src-head/dhash/dhashclient.h	2003-07-25 04:24:11.000000000 -0400
+++ chord-src-noauth/dhash/dhashclient.h	2003-07-25 04:34:56.000000000 -0400
@@ -25,17 +25,25 @@
   chordID guess;
 };
 
-
 class dhashclient
 {
 private:
   ptr<aclnt> gwclnt;
 
-  // inserts under the specified key
-  // (buf need not remain involatile after the call returns)
-  void insert (bigint key, const char *buf, size_t buflen, 
-	       cbinsertgw_t cb,  dhash_ctype t, 
-	       size_t realsize, ptr<option_block> options = NULL);
+  // inserts under the specified chordid
+  // (buf need not remain involatile after the call returns). renamed
+  // to insert_togateway() from insert() b/c it seemed confusing to have
+  // so many insert methods floating around, some of which are private and
+  // some public. --MW
+  void insert_togateway (bigint chordid, const char *buf, size_t buflen, 
+	                 cbinsertgw_t cb,  dhash_ctype t, 
+	                 size_t realsize, ptr<option_block> options = NULL);
+
+  // represents insert functions common to NOAUTH blocks and CONTENT_HASH
+  // blocks
+  void insert_worker_nopk (bigint key, const char* buf, size_t buflen,
+                           cbinsertgw_t cb, dhash_ctype t,
+                           ptr<option_block> options = NULL);
 
   void insertcb (cbinsertgw_t cb, bigint key, 
 		 ptr<dhash_insert_res>, clnt_stat err);
@@ -47,23 +55,46 @@
   // communicate to lsd. 
   dhashclient(str sockname);
 
-  //this version connects to the dhash service on TCP this is for RSC
+  //this version connects to the dhash service on TCP; this is for RSC
   dhashclient(ptr<axprt_stream> xprt);
 
   void append (chordID to, const char *buf, size_t buflen, cbinsertgw_t cb);
 
   // inserts under the contents hash.  (buf need not remain involatile
-  // after the call returns)
+  // after the call returns). The first of these methods will compute the
+  // correct chordid and then call the second of these methods
   void insert (const char *buf, size_t buflen, cbinsertgw_t cb, 
 	       ptr<option_block> options = NULL);
   void insert (bigint key, const char *buf, size_t buflen, cbinsertgw_t cb,
                ptr<option_block> options = NULL);
 
-  // insert under hash of public key
+  // insert under hash of (public key,salt). users of this function are
+  // responsible for constructing a keyhash_payload object. This object
+  // encapsulates the (salt,version,actual_payload) triple.
   void insert (bigint hash, sfs_pubkey2 pk, sfs_sig2 sig,
                keyhash_payload &p,
 	       cbinsertgw_t cb, ptr<option_block> options = NULL);
 
+  // Shoot-yourself-in-the-foot insert method. dhash performs no checks 
+  // on the buf vs. the chordkey, and applications are free to select the
+  // chordkey in the manner of their choosing. 
+  // A note about this method's name: I would like to be consistent and a) either
+  // have all of the insert methods that are public be named 'insert' or b)
+  // avoid overloading the 'insert' name and instead have method names like
+  // insert_contenthash, insert_pkhash, etc. Unfortunately,
+  // option a) isn't quite possible since NOAUTH and CONTENTHASH would have
+  // the same function signatures, and option a) is also a bit unnatural, since
+  // it forces users to communicate their decision about block type to dhash
+  // by their choice of parameters. (It would be one thing if block type were
+  // hidden from applications, but it isn't. The retrieve() method, e.g., actually
+  // asks for the block type.) Finally, option b) isn't possible without
+  // breaking existing applications. So for now, we keep the semantics of the
+  // existing CONTENTHASH 'insert' methods constant. The price is a bit of
+  // inconsistency w.r.t. naming: insert() means CONTENTHASH or KEYASH and is
+  // demultiplexed by parameter choice while insert_noauth() means NOAUTH.
+  void insert_noauth (bigint key, const char *buf, size_t buflen,
+                      cbinsertgw_t cb, ptr<option_block> options = NULL);
+
   // retrieve block and verify
   void retrieve (bigint key, cb_cret cb, ptr<option_block> options = NULL);
   void retrieve (bigint key, dhash_ctype ct, cb_cret cb, 
@@ -73,3 +104,5 @@
 
 #endif
 
+
+
diff -ru chord-src-head/dhash/dhash_common.h chord-src-noauth/dhash/dhash_common.h
--- chord-src-head/dhash/dhash_common.h	2003-07-25 04:24:11.000000000 -0400
+++ chord-src-noauth/dhash/dhash_common.h	2003-07-25 04:34:56.000000000 -0400
@@ -114,4 +114,5 @@
   static ptr<keyhash_payload> decode (ptr<dhash_block> b);
 };
 
+
 #endif /* _DHASH_COMMON_ */
diff -ru chord-src-head/dhash/dhash_impl.h chord-src-noauth/dhash/dhash_impl.h
--- chord-src-head/dhash/dhash_impl.h	2003-07-16 16:42:25.000000000 -0400
+++ chord-src-noauth/dhash/dhash_impl.h	2003-07-25 04:34:56.000000000 -0400
@@ -112,7 +112,11 @@
   ihash<int, pk_partial, &pk_partial::cookie, 
     &pk_partial::link> pk_cache;
   
-  unsigned keyhash_mgr_rpcs;
+  unsigned k_mgr_rpcs_out;
+
+  // encapsulates functionality common to opening a database and reporting
+  // an error
+  void open_worker(ptr<dbfe> db, str name, dbOptions opts, str desc);
 
   void missing (ptr<location> from, bigint key);
   void missing_retrieve_cb (bigint key, dhash_stat err, ptr<dhash_block> b,
@@ -178,7 +182,6 @@
   void dbdelete (ref<dbrec> key);
 
   vec<ptr<location> > replicas;
-  timecb_t *check_replica_tcb;
   timecb_t *merkle_rep_tcb;
   timecb_t *keyhash_mgr_tcb;
 
diff -ru chord-src-head/dhash/server.C chord-src-noauth/dhash/server.C
--- chord-src-head/dhash/server.C	2003-07-24 22:39:27.000000000 -0400
+++ chord-src-noauth/dhash/server.C	2003-07-25 04:34:56.000000000 -0400
@@ -140,42 +140,44 @@
   ss_mode = _ss_mode / 10;
   pk_partial_cookie = 1;
 
-  db = New refcounted<dbfe>();
-  
   //set up the options we want
   dbOptions opts;
   opts.addOption("opt_async", 1);
   opts.addOption("opt_cachesize", 1000);
   opts.addOption("opt_nodesize", 4096);
 
-  if (int err = db->opendb(const_cast < char *>(dbname.cstr()), opts)) {
-    warning << "db file: " << dbname <<"\n";
-    warning << "open returned: " << strerror(err) << "\n";
-    exit (-1);
-  }
- 
+  db = New refcounted<dbfe>();
   cache_db = New refcounted<dbfe> ();
   keyhash_db = New refcounted<dbfe> ();
 
   str cdbs = strbuf() << dbname << ".c";
-  if (int err = cache_db->opendb(const_cast < char *> (cdbs.cstr()), opts)) {
-    warning << "cache db file: " << cdbs <<"\n";
-    warning << "open returned: " << strerror(err) << "\n";
-    exit (-1);
-  }
-
   str kdbs = strbuf() << dbname << ".k";
-  if (int err = keyhash_db->opendb(const_cast < char *> (kdbs.cstr()), opts)) {
-    warning << "keyhash db file: " << kdbs <<"\n";
-    warning << "open returned: " << strerror(err) << "\n";
-    exit (-1);
-  }
+  str kndbs = strbuf() << dbname << ".n";
+  
+  open_worker(db, dbname, opts, "db file");
+  open_worker(cache_db, cdbs, opts, "cache db file");
+  open_worker(keyhash_db, kdbs, opts, "keyhash db file");
 
   // merkle state
   mtree = New merkle_tree (db);
   
 }
 
+
+// encapsulates functionality common to opening a database and reporting
+// an error
+void
+dhash_impl::open_worker(ptr<dbfe> mydb, str name, dbOptions opts, str desc)
+{
+ if (int err = mydb->opendb(const_cast < char *> (name.cstr()), opts)) {
+    warning << desc << ": " << name <<"\n";
+
+    warning << "open returned: " << strerror(err) << "\n";
+    exit (-1);
+  }
+}
+
+
 void
 dhash_impl::init_after_chord(ptr<vnode> node, ptr<route_factory> _r_factory)
 {
@@ -209,8 +211,6 @@
   //don't cache here: only cache on user generated requests
   cli = New dhashcli (node, r_factory, 1); // XXX pick real server selection mode?
 
-  check_replica_tcb = NULL;
-
   /* statistics */
   keys_stored = 0;
   bytes_stored = 0;
@@ -230,7 +230,7 @@
       delaycb (reptm (), wrap (this, &dhash_impl::replica_maintenance_timer, 0));
   }
 
-  keyhash_mgr_rpcs = 0;
+  k_mgr_rpcs_out = 0;
   keyhash_mgr_tcb =
     delaycb (keyhashtm (), wrap (this, &dhash_impl::keyhash_mgr_timer));
   pmaint_obj = New pmaint (cli, host_node, db, 
@@ -305,7 +305,7 @@
 void
 dhash_impl::keyhash_sync_done (dhash_stat err, bool present)
 {
-  keyhash_mgr_rpcs --;
+  k_mgr_rpcs_out --;
 }
 
 void
@@ -314,7 +314,7 @@
   keyhash_mgr_tcb = NULL;
   update_replica_list ();
 
-  if (keyhash_mgr_rpcs == 0) {
+  if (k_mgr_rpcs_out == 0) {
     ptr<dbEnumeration> iter = keyhash_db->enumerate ();
     ptr<dbPair> entry = iter->nextElement (id2dbrec(0));
     while (entry) {
@@ -323,14 +323,14 @@
         // replicate a block if we are responsible for it
         for (unsigned j=0; j<replicas.size(); j++) {
 	  // trace << "keyhash: " << n << " to " << replicas[j]->id () << "\n";
-          keyhash_mgr_rpcs ++;
+          k_mgr_rpcs_out ++;
           cli->sendblock (replicas[j], blockID(n, DHASH_KEYHASH, DHASH_BLOCK),
 			  keyhash_db,
 			  wrap (this, &dhash_impl::keyhash_sync_done));
 	}
       }
       else {
-        keyhash_mgr_rpcs ++;
+        k_mgr_rpcs_out ++;
         // otherwise, try to sync with the master node
 	//XX ATHICHA: Sending a PK block to the primary. 
 	//            Should ask the block's replicas first who the primary is.
@@ -349,9 +349,9 @@
 dhash_impl::keyhash_mgr_lookup (chordID key, dhash_stat err,
 				vec<chord_node> hostsl, route r)
 {
-  keyhash_mgr_rpcs --;
+  k_mgr_rpcs_out --;
   if (!err) {
-      keyhash_mgr_rpcs ++;
+      k_mgr_rpcs_out ++;
       // trace << "keyhash: sync " << key << " to " << r.back()->id () << "\n";
       cli->sendblock (r.back (), blockID(key, DHASH_KEYHASH, DHASH_BLOCK),
 		      keyhash_db,
@@ -992,10 +992,10 @@
 void
 dhash_impl::stop ()
 {
-  if (check_replica_tcb) {
+  if (keyhash_mgr_tcb) {
     warnx << "stop replica timer\n";
-    timecb_remove (check_replica_tcb);
-    check_replica_tcb = NULL;
+    timecb_remove (keyhash_mgr_tcb);
+    keyhash_mgr_tcb = NULL;
   }
   if (merkle_rep_tcb) {
     timecb_remove (merkle_rep_tcb);
@@ -1139,3 +1139,4 @@
   return true;
 }
 
+
diff -ru chord-src-head/svc/dhash_types.x chord-src-noauth/svc/dhash_types.x
--- chord-src-head/svc/dhash_types.x	2003-07-19 02:04:25.000000000 -0400
+++ chord-src-noauth/svc/dhash_types.x	2003-07-25 04:34:56.000000000 -0400
@@ -22,7 +22,8 @@
   DHASH_STORE_NOVERIFY = 17,
   DHASH_STALE = 18,
   DHASH_CACHED = 19,
-  DHASH_TIMEDOUT = 20
+  DHASH_TIMEDOUT = 20,
+  DHASH_RETRIEVE_NOVERIFY = 21
 };
 
 enum dhash_ctype {


More information about the chord mailing list