Beispiel #1
0
//Store will store a file located at path in the DHT (under key) by
//contacting the node at addr
func Store(key [sha256.Size]byte, path string, addr string) error {
	//do a lookup of the key
	ipaddr, err := chord.Lookup(key, addr)

	file, err := os.Open(path)
	checkError(err)
	if err != nil {
		fmt.Printf("error here (0)\n")
		return err
	}
	defer file.Close()
	document := make([]byte, 4096)
	n, err := file.Read(document)
	checkError(err)
	if err != nil {
		fmt.Printf("error here (1)\n")
		return err
	}

	//create message to send to target ip
	msg := getstoreMsg(key, document[:n])

	//send message TODO: check reply for errors
	_, err = chord.Send(msg, ipaddr)
	if err != nil {
		fmt.Printf("error here (2)\n")
	}

	return err

}
Beispiel #2
0
//Notify is part of the ChordApp interface and will update the
//application by moving files if its predecessor changes
func (fs *FileSystem) Notify(id [sha256.Size]byte, myid [sha256.Size]byte, addr string) {
	fmt.Printf("Predecessor changed to %s.\n", addr)
	dir, err := os.Open(fs.home)
	defer dir.Close()
	checkError(err)
	if err != nil {
		return
	}

	names, err := dir.Readdirnames(0)
	checkError(err)
	if err != nil {
		return
	}

	for _, name := range names {
		var key [sha256.Size]byte
		decoded, err := base32.StdEncoding.DecodeString(name)
		if err != nil {
			//fmt.Printf("file was not encoded.\n")
			continue
		}
		copy(key[:], decoded[:sha256.Size])
		if chord.InRange(id, key, myid) {
			//transfer file.
			fs.cache[name] = true
			file, err := os.Open(fmt.Sprintf("%s/%s", fs.home, name))
			checkError(err)
			if err != nil {
				checkError(err)
			}
			defer file.Close()
			document := make([]byte, 4096)
			n, err := file.Read(document)
			checkError(err)
			if err != nil {
				checkError(err)
			}

			//create message to send to target ip
			msg := getstoreMsg(key, document[:n])

			//send message TODO: check reply for errors
			_, err = chord.Send(msg, addr)
			if err != nil {
				checkError(err)
			}

			fmt.Printf("Relocated file %s to node %s.\n", name, addr)

		}
	}

	//TODO: exchange mirrored files

}
Beispiel #3
0
//Fetch will retrieve a file with key specified by key from the DHT and
//save it to path by contacting the node at addr
func Fetch(key [sha256.Size]byte, path string, addr string) error {
	ipaddr, err := chord.Lookup(key, addr)
	if err != nil {
		name := base32.StdEncoding.EncodeToString(key[:])
		err = &FSError{ipaddr, name, err}
		fmt.Printf("%s.\n", err.Error())
		return err
	}

	//create message to send to target ip
	msg := getfetchMsg(key)

	reply, err := chord.Send(msg, ipaddr)
	if err != nil {
		name := base32.StdEncoding.EncodeToString(key[:])
		err = &FSError{ipaddr, name, err}
		fmt.Printf("%s.\n", err.Error())
		return err
	}

	reply, err = parseHeader(reply)
	if err != nil {
		name := base32.StdEncoding.EncodeToString(key[:])
		err = &FSError{ipaddr, name, err}
		fmt.Printf("%s.\n", err.Error())
		return err
	}
	if reply == nil {
		name := base32.StdEncoding.EncodeToString(key[:])
		err = &FSError{ipaddr, name, err}
		fmt.Printf("%s.\n", err.Error())
		return err
	}

	document, err := parseDoc(reply)
	if err != nil {
		name := base32.StdEncoding.EncodeToString(key[:])
		err = &FSError{ipaddr, name, err}
		fmt.Printf("%s.\n", err.Error())
		return err
	}
	if document == nil {
		name := base32.StdEncoding.EncodeToString(key[:])
		err = &FSError{ipaddr, name, err}
		fmt.Printf("%s.\n", err.Error())
		return err
	}

	file, err := os.Create(path)
	checkError(err)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = file.Write(document)
	checkError(err)
	if err != nil {
		return err
	}

	return err

}