Skip to content
Snippets Groups Projects

Reading and writing AChord values

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    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
    }
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment