func main() { var err error var listenStr = flag.String("proxy", "8888", "Proxy listen port (the port you point your browser to)") var dmListenStr = flag.String("d", "localhost:8000", "DryMartini listen address") var connectStr = flag.String("c", "", "DryMartini node to connect to") var isTest = flag.Bool("test", false, "Indicate this node will be used for running test suite") var seed int64 flag.Int64Var(&seed, "s", time.Now().UnixNano(), "seed to use for random generation") // Get the bind and connect connection strings from command-line arguments. flag.Parse() log.Printf("proxy listening on:%s\n", *listenStr) log.Printf("DryMartini opening on:%s\n", *dmListenStr) log.Printf("DryMartini node connecting to:%s\n", *connectStr) log.Printf("is Test:%t\n", *isTest) kademlia.RunningTests = *isTest kademlia.TestStartTime = time.Now().Local() err = os.Mkdir("./logs/", os.ModeDir) logfile, err := os.Create("./logs/complete_log_" + kademlia.TestStartTime.String()) if err != nil { log.Printf("error creating main log:%s\n", err) panic(1) } dbg.InitDbgOut(logfile) rand.Seed(seed) //instantiate myDryMartini = drymartini.NewDryMartini(*dmListenStr, 4096) if *connectStr != "" { success, err := MakePing(myDryMartini, *connectStr) if !success { log.Printf("connect to %s failed. err:%s\n", connectStr, err) panic(1) } drymartini.DoJoin(myDryMartini) } /* host, port, errr := kademlia.AddrStrToHostPort(connectStr) var swarm []*drymartini.DryMartini = drymartini.MakeSwarm(8, int(port)) drymartini.WarmSwarm(myDryMartini, swarm) */ kademlia.PrintLocalBuckets(myDryMartini.KademliaInst) proxy := goproxy.NewProxyHttpServer() proxy.OnRequest().DoFunc(DoHTTPRequest) log.Fatal(http.ListenAndServe(":"+*listenStr, proxy)) /* var stdInReader *bufio.Reader = bufio.NewReader(os.Stdin) var instStr string var inst *DryMartiniInstruction for ;; { fmt.Printf("δώσε:")//Print prompt //read new instruction //ret, err := fmt.Scanln(&instStr) instStr, err = stdInReader.ReadString('\n') if err != nil { log.Printf("Error at Scanf: %s\n", err) panic(1) } //parse line input and create command struct inst = NewDryMartiniInstruction(instStr) if inst.IsExit() { log.Printf("DryMartini exiting.\n\n\nOne for the road, maybe?"); break; } //execute new instruction inst.Execute(myDryMartini) if (myDryMartini.KademliaInst.DoJoinFlag) { log.Printf("DoingJoin!\n") go drymartini.DoJoin(myDryMartini) } } */ log.Printf("end of main\n") }
func (kInst *KademliaInstruction) Execute(k *kademlia.Kademlia) (status bool) { var found bool var remoteContact *kademlia.Contact switch { case kInst.IsExit(): if kademlia.RunningTests { log.Printf("Executing Exit Instruction\n") } return true case kInst.IsSkip(): if kademlia.RunningTests { log.Printf("Executing Skip Instruction: _%s_\n", kInst.Data) } return true case kInst.IsPing(): var success bool if kInst.Addr != "" { //ping host:port log.Printf("Executing Ping Instruction 'ping Addr:%s\n", kInst.Addr) remoteHost, remotePort, err := kademlia.AddrStrToHostPort(kInst.Addr) kademlia.Assert(err == nil, "Error converting AddrToHostPort") success = kademlia.MakePingCall(k, remoteHost, remotePort) } else { //ping nodeID log.Printf("Executing Ping Instruction 'ping nodeID:%s\n", kInst.NodeID.AsString()) var searchRequest *kademlia.SearchRequest searchRequest = &kademlia.SearchRequest{kInst.NodeID, make(chan *kademlia.Contact)} k.SearchChannel <- searchRequest remoteContact = <-searchRequest.ReturnChan found = (remoteContact != nil) if found { success = kademlia.MakePingCall(k, remoteContact.Host, remoteContact.Port) } else { log.Printf("Error: Ping, nodeID %s could not be found\n", kInst.NodeID.AsString()) return false } } return success case kInst.IsStore(): var searchRequest *kademlia.SearchRequest var success bool if kademlia.RunningTests { log.Printf("Executing Store Instruction %s %s %s\n", kInst.NodeID.AsString(), kInst.Key.AsString(), kInst.Data) } searchRequest = &kademlia.SearchRequest{kInst.NodeID, make(chan *kademlia.Contact)} k.SearchChannel <- searchRequest remoteContact = <-searchRequest.ReturnChan found = (remoteContact != nil) if found { success = kademlia.MakeStore(k, remoteContact, kInst.Key, []byte(kInst.Data)) } else { log.Printf("Error: Store, nodeID %s could not be found\n", kInst.NodeID.AsString()) return false } return success case kInst.IsFindNode(): var searchRequest *kademlia.SearchRequest var success bool if kademlia.RunningTests { log.Printf("Executing FindNode Instruction %s %s\n", kInst.NodeID.AsString(), kInst.Key.AsString()) } searchRequest = &kademlia.SearchRequest{kInst.NodeID, make(chan *kademlia.Contact)} k.SearchChannel <- searchRequest remoteContact = <-searchRequest.ReturnChan found = (remoteContact != nil) if found { var fsResponseChan chan *kademlia.FindStarCallResponse var findStarResult *kademlia.FindStarCallResponse fsResponseChan = make(chan *kademlia.FindStarCallResponse, 1) go kademlia.MakeFindNodeCall(k, remoteContact, kInst.Key, fsResponseChan) findStarResult = <-fsResponseChan success = findStarResult.Responded if success { kademlia.Assert(findStarResult.ReturnedFNRes != nil, "findStarResult Struct error in FindNode") kademlia.PrintArrayOfFoundNodes(&(findStarResult.ReturnedFNRes.Nodes)) } } else { log.Printf("Error: FindNode, nodeID %s could not be found\n", kInst.NodeID.AsString()) return false } return success case kInst.IsFindValue(): var searchRequest *kademlia.SearchRequest var success bool if kademlia.RunningTests { log.Printf("Executing FindValue Instruction %s %s\n", kInst.NodeID.AsString(), kInst.Key.AsString()) } searchRequest = &kademlia.SearchRequest{kInst.NodeID, make(chan *kademlia.Contact)} k.SearchChannel <- searchRequest remoteContact = <-searchRequest.ReturnChan found = (remoteContact != nil) if found { var fsResponseChan chan *kademlia.FindStarCallResponse var findStarResult *kademlia.FindStarCallResponse fsResponseChan = make(chan *kademlia.FindStarCallResponse, 1) go kademlia.MakeFindValueCall(k, remoteContact, kInst.Key, fsResponseChan) findStarResult = <-fsResponseChan success = findStarResult.Responded if success { kademlia.Assert(findStarResult.ReturnedFVRes != nil, "findStarResult Struct error in FindValue") if findStarResult.ReturnedFVRes.Value != nil { log.Printf("FindValue: found [%s:%s]\n", kInst.Key.AsString(), string(findStarResult.ReturnedFVRes.Value)) } else { log.Printf("FindValue: Could not locate value, printing closest nodes\n") kademlia.PrintArrayOfFoundNodes(&(findStarResult.ReturnedFVRes.Nodes)) } } } else { log.Printf("Error: FindValue, nodeID %s could not be found\n", kInst.NodeID.AsString()) return false } return success case kInst.IsWhoami(): if kademlia.RunningTests { log.Printf("Executing Whoami Instruction\n") fmt.Printf("Local Node ID: %s\n", k.ContactInfo.NodeID.AsString()) } else { fmt.Printf("%s\n", k.ContactInfo.NodeID.AsString()) } return true case kInst.IsLocalFindValue(): if kademlia.RunningTests { log.Printf("Executing LocalFindValue Instruction\n") } localvalue, found := k.ValueStore.Get(kInst.Key) if found { if kademlia.RunningTests { fmt.Printf("Value for key %s --> %s\n", kInst.Key.AsString(), string(localvalue)) } else { fmt.Printf("%s\n", string(localvalue)) } } else { if kademlia.RunningTests { fmt.Printf("Value for Key %s NOT found\n", kInst.Key.AsString()) } else { fmt.Printf("ERR\n") } } return true case kInst.IsGetContact(): var searchRequest *kademlia.SearchRequest if kademlia.RunningTests { log.Printf("Executing GetContact Instruction %s\n", kInst.NodeID.AsString()) } searchRequest = &kademlia.SearchRequest{kInst.NodeID, make(chan *kademlia.Contact)} k.SearchChannel <- searchRequest remoteContact = <-searchRequest.ReturnChan found = (remoteContact != nil) if found { if kademlia.RunningTests { log.Printf("GetContact: Addr:%v, Port: %v\n", remoteContact.Host, remoteContact.Port) } else { fmt.Printf("%v %v\n", remoteContact.Host, remoteContact.Port) } } else { if kademlia.RunningTests { log.Printf("GetContact: Could not locate in local buckets nodeID %s\n", kInst.NodeID.AsString()) } else { fmt.Printf("ERR\n") } } return true case kInst.IsIterativeStore(): var success bool var nodes []kademlia.FoundNode var err error if kademlia.RunningTests { log.Printf("Executing iterativeStore Instruction %s %s\n", kInst.Key.AsString(), kInst.Data) } //NOTE: the third returned value is dropped on the assumption it would always be nil for this call success, nodes, _, err = kademlia.IterativeFind(k, kInst.Key, 1) //findType of 1 is FindNode if err != nil { log.Printf("IterativeFind: Error %s\n", err) return false } if success { if nodes != nil { for _, node := range nodes { kademlia.MakeStore(k, node.FoundNodeToContact(), kInst.Key, []byte(kInst.Data)) } kademlia.PrintArrayOfFoundNodes(&nodes) } else { kademlia.Assert(false, "iterativeFindStore: TODO: This should probably never happen right?") } } return success case kInst.IsIterativeFindNode(): var success bool var nodes []kademlia.FoundNode //var value []byte //This is probably not needed as iterativeFindNode should never return a value var err error if kademlia.RunningTests { log.Printf("Executing iterativeFindNode Instruction %s\n", kInst.NodeID.AsString()) } //NOTE: the third returned value is dropped on the assumption it would always be nil for this call success, nodes, _, err = kademlia.IterativeFind(k, kInst.NodeID, 1) //findType of 1 is FindNode if err != nil { log.Printf("IterativeFind: Error %s\n", err) return false } if success { if nodes != nil { kademlia.PrintArrayOfFoundNodes(&nodes) } else { kademlia.Assert(false, "iterativeFindNode: TODO: This should probably never happen right?") } } return success case kInst.IsIterativeFindValue(): var success bool var nodes []kademlia.FoundNode var value []byte var err error if kademlia.RunningTests { log.Printf("Executing iterativeFindValue Instruction %s\n", kInst.Key.AsString()) } success, nodes, value, err = kademlia.IterativeFind(k, kInst.Key, 2) //findType of 2 is FindValue if err != nil { log.Printf("IterativeFind: Error %s\n", err) return false } if success { if value != nil { if kademlia.RunningTests { fmt.Printf("iterativeFindValue: Value for key %s --> %s\n", kInst.Key.AsString(), string(value)) } else { fmt.Printf("%v %v\n", nodes[0].NodeID, value) } } else { if kademlia.RunningTests { fmt.Printf("iterativeFindValue: Value for key %s NOT FOUND\n", kInst.Key.AsString()) kademlia.PrintArrayOfFoundNodes(&nodes) } else { fmt.Printf("ERR") } } } return success case kInst.IsRunTests(): log.Printf("Executing RunTests!\n") kademlia.RunTests(kInst.Data) return true case kInst.IsPrintLocalBuckets(): log.Printf("Print Local Buckets!\n") kademlia.PrintLocalBuckets(k) return true case kInst.IsPrintLocalData(): log.Printf("Print Local Data!\n") kademlia.PrintLocalData(k) return true } return false }
func (dmInst *DryMartiniInstruction) Execute(dm *drymartini.DryMartini) (status bool) { var err error switch { case dmInst.IsExit(): if Verbose { log.Printf("Executing Exit Instruction\n") } return true case dmInst.IsSkip(): if Verbose { log.Printf("Executing Skip Instruction: _%s_\n", dmInst.CmdStr) } return true case dmInst.IsPing(): var success bool if Verbose { log.Printf("Executing Ping Instruction 'ping Addr:%s\n", dmInst.Addr) } remoteHost, remotePort, err := kademlia.AddrStrToHostPort(dmInst.Addr) if err != nil { log.Printf("Error converting AddrToHostPort, %s", err) os.Exit(1) } success = drymartini.MakeMartiniPing(dm, remoteHost, remotePort) return success case dmInst.IsJoin(): if Verbose { log.Printf("Executing MartiniJoin Instruction\n") } //remoteHost, remotePort, err := kademlia.AddrStrToHostPort(dmInst.Addr) //drymartini.MakeJoin(dm, remoteHost, remotePort) //if err != nil { // log.Printf("Error converting AddrToHostPort, %s", err) // os.Exit(1) //} return true case dmInst.IsWhoami(): if Verbose { log.Printf("Executing Whoami Instruction\n") fmt.Printf("Local Node ID: %s\n", dm.KademliaInst.ContactInfo.NodeID.AsString()) } else { fmt.Printf("%s\n", dm.KademliaInst.ContactInfo.NodeID.AsString()) } return true case dmInst.IsPrintLocalBuckets(): log.Printf("Print Local Buckets!\n") kademlia.PrintLocalBuckets(dm.KademliaInst) return true case dmInst.IsPrintLocalData(): log.Printf("Print Local Data!\n") //kademlia.PrintLocalData(dm.KademliaInst) drymartini.PrintLocalData(dm) return true case dmInst.IsPrintLocalFlowData(): log.Printf("Print Local FlowData!\n") drymartini.PrintLocalFlowData(dm) return true case dmInst.IsGeneratePath(): log.Printf("Generate Path\n") drymartini.GeneratePath(dm, dmInst.minNodes, dmInst.maxNodes) return true case dmInst.IsBarCrawl(): log.Printf("Bar Crawl (negotiating symmkeys with nodes)") drymartini.BarCrawl(dm, dmInst.request, dmInst.minNodes, dmInst.maxNodes) case dmInst.IsFindValue(): log.Printf("Find Value") var sucess bool //var nodes[]kademlia.FoundNode var value []byte sucess, _, value, err = kademlia.IterativeFind(dm.KademliaInst, dmInst.Key, 2) if err != nil { log.Printf("IterativeFind: error %s\n", err) } if sucess { if value != nil { log.Printf("IterativeFindValue err: success = true. value is nil\n") } } case dmInst.IsSend(): log.Printf("Send %d %s\n", dmInst.FlowIndex, dmInst.request) drymartini.SendData(dm, dmInst.FlowIndex, dmInst.request) case dmInst.IsMakeSwarm(): log.Printf("Making swarm: numNodes:%d\n", dmInst.minNodes) var swarm []*drymartini.DryMartini = drymartini.MakeSwarm(dmInst.minNodes, dmInst.maxNodes, time.Now().UnixNano()) drymartini.WarmSwarm(dm, swarm, rand.New(rand.NewSource(time.Now().UnixNano()))) case dmInst.IsRunTests(): log.Printf("Running tests: numNodes:%d\n", dmInst.minNodes) drymartini.RunTests(dm, dmInst.minNodes, dmInst.maxNodes, time.Now().UnixNano(), 4, 4) case dmInst.IsSleep(): log.Printf("Sleeping %d ms\n", dmInst.minNodes) time.Sleep(time.Millisecond * time.Duration(dmInst.minNodes)) case dmInst.IsBlock(): fmt.Printf("Blocking comm on node\n") log.Printf("Blocking comm on this node\n") dm.KademliaInst.KListener.Close() case dmInst.IsOpen(): fmt.Printf("Accepting comm on node again\n") log.Printf("Accepting comms again\n") go http.Serve(dm.KademliaInst.KListener, nil) case dmInst.IsBCAndSend(): log.Printf("bc and send\n") success, index := drymartini.FindGoodPath(dm) if !success { success, index = drymartini.BarCrawl(dm, dmInst.request, dmInst.minNodes, dmInst.maxNodes) if !success { log.Printf("Error: main. bcandsend; bc failed\n") return } } drymartini.SendData(dm, index, dmInst.request) } return false }