Reading and writing AChord values
The snippet can be accessed without any authentication.
Authored by
Lars Seipel
buf.go 2.46 KiB
// Retrieve value from AChord and decrypt it.
func (c *Client) achordGet(b *buf) error {
p := c.bufGet()
defer c.bufPut(p)
var n int
var err error
// BUG(ls): The decision to backoff and retry should be left to
// callers. We have no good way to do that yet. We should probably
// start by threading context values throughout the FS code so we can
// at least support cancelation. Clients then cancel the contexts to
// stop the retry loop. Especially important for FUSE as programs
// accessing the FS end up unkillable if we don't do this.
for i := 0; i < 10; i++ {
n, err = c.kv.Get(context.TODO(), b.addr[:], p.data)
if err == nil {
break
}
if !netutil.IsTemporary(err) {
return err
}
backoff(i, err)
}
if err != nil {
return err
}
if n < blockOverhead {
return syscall.EIO
}
pp := p.data[:n]
var nonce [24]byte
pp = pp[copy(nonce[:], pp):]
zp, ok := secretbox.Open(nil, pp, &nonce, &c.key)
if !ok {
return errAuth
}
q := zp
if b.addr != c.sbp {
q, err = c.decode(nil, zp)
if err != nil {
return err
}
}
copy(b.data, q)
b.flags |= bufValid
return nil
}
// Encrypt buffer and upload it to AChord.
func (c *Client) achordPut(b *buf) error {
p := c.bufGet()
defer c.bufPut(p)
zp := b.data
if b.addr != c.sbp {
// never compress or otherwise transform the superblock
zp = c.encode(nil, b.data)
}
var nonce [24]byte
if _, err := rand.Read(nonce[:]); err != nil {
return err
}
pp := p.data[copy(p.data, nonce[:]):]
q := secretbox.Seal(pp[:0], zp, &nonce, &c.key)
var err error
for i := 0; i < 10; i++ {
err = c.kv.Put(context.TODO(), b.addr[:], p.data[:len(nonce)+len(q)])
if err == nil {
b.flags &^= bufDirty
break
}
if !netutil.IsTemporary(err) {
return err
}
backoff(i, err)
}
return err
}
Please register or sign in to comment