Esempio n. 1
0
func doPing(kadem *kademlia.Kademlia, con kademlia.Contact, addressOrId string) {
	var pingAddress string
	if len(strings.Split(addressOrId, string(":"))) == 2 {
		pingAddress = addressOrId
	} else {
		id, err := kademlia.FromString(addressOrId)
		if err != nil {
			fmt.Printf("ERR could not interpret nodeid as ID")
			return
		}
		con, err := kadem.ContactFromID(id)
		if err != nil {
			fmt.Println("ERR : unknown node")
			return
		}
		pingAddress = contactToAddrString(con)
	}
	client, err := rpc.DialHTTP("tcp", pingAddress)
	if err != nil {
		log.Fatal("DialHTTP: ", err)
	}
	ping := kademlia.Ping{Sender: con}
	ping.MsgID = kademlia.NewRandomID()
	var pong kademlia.Pong
	err = client.Call("Kademlia.Ping", ping, &pong)
	if err != nil {
		log.Fatal("Call: ", err)
	}

	if ping.MsgID.Equals(pong.MsgID) {
		fmt.Print("OK\n")
	} else {
		fmt.Print("ERR : response message id does not match\n")
	}
	_ = client.Close()
}
Esempio n. 2
0
func executeLine(k *kademlia.Kademlia, line string) (response string) {
	toks := strings.Fields(line)
	switch {
	case toks[0] == "quit":
		response = "quit"
	case toks[0] == "whoami":
		if len(toks) > 1 {
			response = "usage: whoami"
			return
		}
		response = k.NodeID.AsString()

	case toks[0] == "print_contact":
		if len(toks) < 2 || len(toks) > 2 {
			response = "usage: print_contact [nodeID]"
			return
		}
		id, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Not a valid node ID (" + toks[1] + ")"
			return
		}
		c, err := k.FindContact(id)
		if err != nil {
			response = "ERR: Unknown contact node ID"
			return
		}
		response = "OK: NodeID=" + toks[1] + "\n"
		response += "      Host=" + c.Host.String() + "\n"
		response += "      Port=" + strconv.Itoa(int(c.Port))
	case toks[0] == "ping":
		// Do a ping
		// Check if toks[1] is a valid NodeID, if not, try pinging host:port
		// print an error if neither is valid
		// Following lines need to be expanded

		if len(toks) < 2 || len(toks) > 2 {
			response = "usage: ping [nodeID | host:port]"
			return
		}
		id, err := kademlia.IDFromString(toks[1])
		if err != nil {
			hostname, portstr, err := net.SplitHostPort(toks[1])
			if err != nil {
				response = "ERR: Not a valid Node ID or host:port address"
				return
			}
			port, err := strconv.Atoi(portstr)
			if err != nil {
				response = "ERR: Not a valid Node ID or host:port address"
				return
			}
			ipAddrStrings, err := net.LookupHost(hostname)
			if err != nil {
				response = "ERR: Could not find the provided hostname"
				return
			}
			var host net.IP
			for i := 0; i < len(ipAddrStrings); i++ {
				host = net.ParseIP(ipAddrStrings[i])
				if host.To4() != nil {
					break
				}
			}
			response = k.DoPing(host, uint16(port))
			return
		}
		c, err := k.FindContact(id)
		if err != nil {
			response = "ERR: Not a valid Node ID or host:port address"
			return
		}
		response = k.DoPing(c.Host, c.Port)

	case toks[0] == "local_find_value":
		// print a local variable
		if len(toks) < 2 || len(toks) > 2 {
			response = "usage: local_find_value [key]"
			return
		}
		key, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Provided an invalid key (" + toks[1] + ")"
			return
		}
		response = k.LocalFindValue(key)

	case toks[0] == "store":
		// Store key, value pair at NodeID
		if len(toks) < 4 || len(toks) > 4 {
			response = "usage: store [nodeID] [key] [value]"
			return
		}
		nodeId, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Provided an invalid node ID (" + toks[1] + ")"
			return
		}
		contact, err := k.FindContact(nodeId)
		if err != nil {
			response = "ERR: Unable to find contact with node ID (" + toks[1] + ")"
			return
		}
		key, err := kademlia.IDFromString(toks[2])
		if err != nil {
			response = "ERR: Provided an invalid key (" + toks[2] + ")"
			return
		}
		value := []byte(toks[3])

		response = k.DoStore(contact, key, value)

	case toks[0] == "vanish":
		if len(toks) < 5 || len(toks) > 5 {
			response = "usage : vanish [VDO ID] [data] [numberKeys] [threshold]"
			return
		}
		vdoId, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Provided an invalid node ID (" + toks[1] + ")"
			return
		}
		value := []byte(toks[2])
		numberKeys, _ := strconv.Atoi(toks[3])
		threshold, _ := strconv.Atoi(toks[4])
		vdo := kademlia.VanishData(*k, value, byte(numberKeys), byte(threshold))
		k.SelfVDOT.Put(vdoId, vdo)

	case toks[0] == "unvanish":
		if len(toks) < 3 || len(toks) > 3 {
			response = "usage : unvanish [Node ID] [VDO ID]"
			return
		}
		nodeId, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Provided an invalid node ID (" + toks[1] + ")"
			return
		}
		vdoId, err := kademlia.IDFromString(toks[2])
		if err != nil {
			response = "ERR: Provided an invalid node ID (" + toks[1] + ")"
			return
		}
		contact, err := k.FindContact(nodeId)
		if err != nil {
			response = "ERR: Unable to find contact with node ID (" + toks[1] + ")"
			return
		}
		response, _ = k.DoGetVDO(*contact, vdoId)

	case toks[0] == "find_node":
		// perform a find_node RPC
		if len(toks) < 3 || len(toks) > 3 {
			response = "usage: find_node [nodeID] [key]"
			return
		}

		nodeId, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Provided an invalid node ID (" + toks[1] + ")"
			return
		}
		contact, err := k.FindContact(nodeId)
		if err != nil {
			response = "ERR: Unable to find contact with node ID (" + toks[1] + ")"
			return
		}
		key, err := kademlia.IDFromString(toks[2])
		if err != nil {
			response = "ERR: Provided an invalid key (" + toks[2] + ")"
			return
		}
		response, _ = k.DoFindNode(contact, key)

	case toks[0] == "find_value":
		// perform a find_value RPC
		if len(toks) < 3 || len(toks) > 3 {
			response = "usage: find_value [nodeID] [key]"
			return
		}

		nodeId, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Provided an invalid node ID (" + toks[1] + ")"
			return
		}
		contact, err := k.FindContact(nodeId)
		if err != nil {
			response = "ERR: Unable to find contact with node ID (" + toks[1] + ")"
			return
		}
		key, err := kademlia.IDFromString(toks[2])
		if err != nil {
			response = "ERR: Provided an invalid key (" + toks[2] + ")"
			return
		}
		response, _ = k.DoFindValue(contact, key)

	case toks[0] == "iterativeFindNode":
		// perform an iterative find node
		if len(toks) != 2 {
			response = "usage: iterativeFindNode [nodeID]"
			return
		}
		id, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Provided an invalid node ID(" + toks[1] + ")"
			return
		}
		response, _ = k.DoIterativeFindNode(id)

	case toks[0] == "iterativeStore":
		// perform an iterative store
		if len(toks) != 3 {
			response = "usage: iterativeStore [key] [value]"
			return
		}
		key, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Provided an invalid key (" + toks[1] + ")"
			return
		}
		response, _ = k.DoIterativeStore(key, []byte(toks[2]))

	case toks[0] == "iterativeFindValue":
		// performa an iterative find value
		if len(toks) != 2 {
			response = "usage: iterativeFindValue [key]"
			return
		}
		key, err := kademlia.IDFromString(toks[1])
		if err != nil {
			response = "ERR: Provided an invalid key (" + toks[1] + ")"
			return
		}
		response, _ = k.DoIterativeFindValue(key)

	default:
		response = "ERR: Unknown command"
	}
	return
}