[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