//given an ID, searches the local store, DHT, and if found unmarshals the bytes into a MartiniContact func findMartiniContact(dm *DryMartini, hashedID kademlia.ID) (MartiniContact, bool) { var mcBytes []byte var mc MartiniContact var err error var success bool mcBytes, success = dm.KademliaInst.ValueStore.Get(hashedID) if !success { success, _, mcBytes, err = kademlia.IterativeFind(dm.KademliaInst, hashedID, 2) if err != nil { dbg.Printf("findingMartiniContact failed. searching for key:%s. err:%s\n", ERRORS, hashedID.AsString(), err) return mc, false } if success { dbg.Printf("findMartiniContact: foundValue\n", Verbose) } else { dbg.Printf("IterativeFind failed to findvalue for key:%s\n", ERRORS, hashedID.AsString()) return mc, false } } else { //dbg.Printf("found martiniContact locally. Key:%+v\n", hashedID) } err = json.Unmarshal(mcBytes, &mc) dbg.Printf("findMartiniContact: 'foundContact.NodeIP:%s, Port:%d\n", Verbose, mc.NodeIP, mc.NodePort) if err != nil { dbg.Printf("Error unmarshaling found MartiniContact. %s\n", ERRORS, err) panic(1) } return mc, true }
//stores dm's contactInfo in the DHT func StoreContactInfo(dm *DryMartini) { var err error var mcBytes []byte var key kademlia.ID = dm.KademliaInst.ContactInfo.NodeID.SHA1Hash() mcBytes, err = json.Marshal(dm.myMartiniContact) if err != nil { dbg.Printf("error marshalling MartiniContact: %s\n", true, err) } var m MartiniContact err = json.Unmarshal(mcBytes, &m) if err != nil { dbg.Printf("error: drymartini.PrintLocalData %s\n", (err != nil), err) } dbg.Printf("Print HashMap[%s]=%+v\n", Verbose, key.AsString(), m) dbg.Printf("storing martiniContact:%+v %+v at ID: %x\n", Verbose, dm.myMartiniContact, mcBytes, key) kademlia.MakeIterativeStore(dm.KademliaInst, key, mcBytes) go func() { //republish contact info ever 4 minutes. (expire time is hardcoded at 5minutes in kademlia.rpc) for { time.Sleep(time.Duration(4) * time.Minute) kademlia.MakeIterativeStore(dm.KademliaInst, key, mcBytes) } }() }
//returns array of random known-to-be-live MartiniContacts (for use as a path) func GeneratePath(dm *DryMartini, min, max int) (mcPath []MartiniContact) { const safetyMax int = 50 var err error //var threshold int //var myRand *big.Int var randId kademlia.ID var pathMap map[MartiniContact]bool = make(map[MartiniContact]bool) //minBig := big.NewInt(int64(min)) //myRand, err = rand.Int(rand.Reader, big.NewInt(int64(max-min))) //threshold = int((minBig.Int64() + myRand.Int64())) mcPath = make([]MartiniContact, max) var safetyCounter int = 0 for i := 0; i < max; i++ { var foundNodes []kademlia.FoundNode var success bool safetyCounter++ dbg.Printf("Attempt %d to add to path (curlength %d)\n", Verbose, safetyCounter, i) if safetyCounter == safetyMax { dbg.Printf("GeneratePath failure. Made %d attempts. unable to get enough MartiniContacts to build path of length:%d\n", ERRORS, safetyMax, max) panic(1) } randId = kademlia.NewRandomID() success, foundNodes, _, err = kademlia.IterativeFind(dm.KademliaInst, randId, 1) if len(foundNodes) == 0 { dbg.Printf("GeneratePath:316. no nodes found; continueing\n", Verbose) i-- continue } /* dbg.Printf("GeneratePath: found live nodes:\n") kademlia.PrintArrayOfFoundNodes(&foundNodes) */ if err != nil { dbg.Printf("error finding random NodeID:%s, success:%s msg:%s\n", ERRORS, randId, success, err) panic(1) } fuckthis, fuckingo := rand.Int(rand.Reader, big.NewInt(int64(len(foundNodes)))) if fuckingo != nil { dbg.Printf("error making rand:%s\n", ERRORS, fuckingo) } index := int(fuckthis.Int64()) var hashedID kademlia.ID = foundNodes[index].NodeID.SHA1Hash() dbg.Printf("generatePath: findMartiniContact for mc:%+v\n", Verbose, foundNodes[index]) var tempMC MartiniContact tempMC, success = findMartiniContact(dm, hashedID) if !success { dbg.Printf("error finding MartiniContact with key:%s. err:%s\n", ERRORS, hashedID.AsString(), err) i-- continue } _, alreadyInPath := pathMap[tempMC] if alreadyInPath { dbg.Printf("trying to make a circular path. skipping!\n", Verbose) i-- continue } else { pathMap[tempMC] = true mcPath[i] = tempMC } //err = json.Unmarshal(mcBytes, &mcPath[i]) dbg.Printf("GeneratePath path-mid-build: %+v\n", Verbose, mcPath) } return }