func (d *Discoverer) externalLookup(node string) (string, bool) { extIP, err := net.ResolveUDPAddr("udp", d.extServer+":22025") if err != nil { log.Printf("discover/external: %v; no external lookup", err) return "", false } conn, err := net.DialUDP("udp", nil, extIP) if err != nil { log.Printf("discover/external: %v; no external lookup", err) return "", false } defer conn.Close() err = conn.SetDeadline(time.Now().Add(5 * time.Second)) if err != nil { log.Printf("discover/external: %v; no external lookup", err) return "", false } _, err = conn.Write(EncodePacket(Packet{QueryMagic, 0, node, nil})) if err != nil { log.Printf("discover/external: %v; no external lookup", err) return "", false } var buf = buffers.Get(256) defer buffers.Put(buf) n, err := conn.Read(buf) if err != nil { if err, ok := err.(net.Error); ok && err.Timeout() { // Expected if the server doesn't know about requested node ID return "", false } log.Printf("discover/external/read: %v; no external lookup", err) return "", false } pkt, err := DecodePacket(buf[:n]) if err != nil { log.Printf("discover/external/read: %v; no external lookup", err) return "", false } if pkt.Magic != AnnouncementMagic { log.Printf("discover/external/read: bad magic; no external lookup", err) return "", false } return fmt.Sprintf("%s:%d", ipStr(pkt.IP), pkt.Port), true }
func (r *marshalReader) readBytes() []byte { if r.err != nil { return nil } l := int(r.readUint32()) if r.err != nil { return nil } if l > maxBytesFieldLength { r.err = ErrFieldLengthExceeded return nil } b := buffers.Get(l + pad(l)) _, r.err = io.ReadFull(r.r, b) atomic.AddUint64(&r.tot, uint64(l+pad(l))) return b[:l] }
// Request returns the specified data segment by reading it from local disk. // Implements the protocol.Model interface. func (m *Model) Request(nodeID, repo, name string, offset int64, size int) ([]byte, error) { // Verify that the requested file exists in the local model. m.rmut.RLock() r, ok := m.repoFiles[repo] m.rmut.RUnlock() if !ok { l.Warnf("Request from %s for file %s in nonexistent repo %q", nodeID, name, repo) return nil, ErrNoSuchFile } lf := r.Get(cid.LocalID, name) if lf.Suppressed || lf.Flags&protocol.FlagDeleted != 0 { if debug { l.Debugf("REQ(in): %s: %q / %q o=%d s=%d; invalid: %v", nodeID, repo, name, offset, size, lf) } return nil, ErrInvalid } if offset > lf.Size { if debug { l.Debugf("REQ(in; nonexistent): %s: %q o=%d s=%d", nodeID, name, offset, size) } return nil, ErrNoSuchFile } if debug && nodeID != "<local>" { l.Debugf("REQ(in): %s: %q / %q o=%d s=%d", nodeID, repo, name, offset, size) } m.rmut.RLock() fn := filepath.Join(m.repoDirs[repo], name) m.rmut.RUnlock() fd, err := os.Open(fn) // XXX: Inefficient, should cache fd? if err != nil { return nil, err } defer fd.Close() buf := buffers.Get(int(size)) _, err = fd.ReadAt(buf, offset) if err != nil { return nil, err } return buf, nil }
func (p *puller) handleCopyBlock(b bqBlock) { // We have blocks to copy from the existing file f := b.file of := p.openFiles[f.Name] if debug { l.Debugf("pull: copying %d blocks for %q / %q", len(b.copy), p.repo, f.Name) } var exfd *os.File exfd, of.err = os.Open(of.filepath) if of.err != nil { if debug { l.Debugf("pull: error: %q / %q: %v", p.repo, f.Name, of.err) } of.file.Close() of.file = nil p.openFiles[f.Name] = of return } defer exfd.Close() for _, b := range b.copy { bs := buffers.Get(int(b.Size)) _, of.err = exfd.ReadAt(bs, b.Offset) if of.err == nil { _, of.err = of.file.WriteAt(bs, b.Offset) } buffers.Put(bs) if of.err != nil { if debug { l.Debugf("pull: error: %q / %q: %v", p.repo, f.Name, of.err) } exfd.Close() of.file.Close() of.file = nil p.openFiles[f.Name] = of return } } }
func (m *Model) Request(nodeID, name string, offset uint64, size uint32, hash []byte) ([]byte, error) { if opts.Debug.TraceNet && nodeID != "<local>" { debugf("NET REQ(in): %s: %q o=%d s=%d h=%x", nodeID, name, offset, size, hash) } fn := path.Join(m.dir, name) fd, err := os.Open(fn) // XXX: Inefficient, should cache fd? if err != nil { return nil, err } defer fd.Close() buf := buffers.Get(int(size)) _, err = fd.ReadAt(buf, int64(offset)) if err != nil { return nil, err } return buf, nil }
// Request returns the specified data segment by reading it from local disk. // Implements the protocol.Model interface. func (m *Model) Request(nodeID, name string, offset int64, size uint32, hash []byte) ([]byte, error) { // Verify that the requested file exists in the local and global model. m.lmut.RLock() lf, localOk := m.local[name] m.lmut.RUnlock() m.gmut.RLock() _, globalOk := m.global[name] m.gmut.RUnlock() if !localOk || !globalOk { log.Printf("SECURITY (nonexistent file) REQ(in): %s: %q o=%d s=%d h=%x", nodeID, name, offset, size, hash) return nil, ErrNoSuchFile } if lf.Flags&protocol.FlagInvalid != 0 { return nil, ErrInvalid } if m.trace["net"] && nodeID != "<local>" { log.Printf("NET REQ(in): %s: %q o=%d s=%d h=%x", nodeID, name, offset, size, hash) } fn := path.Join(m.dir, name) fd, err := os.Open(fn) // XXX: Inefficient, should cache fd? if err != nil { return nil, err } defer fd.Close() buf := buffers.Get(int(size)) _, err = fd.ReadAt(buf, offset) if err != nil { return nil, err } if m.limitRequestRate != nil { for s := 0; s < len(buf); s += 1024 { <-m.limitRequestRate } } return buf, nil }
func (m *fileMonitor) copyLocalBlocks(inFile, outFile *os.File, writeWg *sync.WaitGroup) { defer inFile.Close() defer writeWg.Done() var buf = buffers.Get(BlockSize) defer buffers.Put(buf) for _, lb := range m.localBlocks { buf = buf[:lb.Size] _, err := inFile.ReadAt(buf, lb.Offset) if err != nil { m.copyError = err return } _, err = outFile.WriteAt(buf, lb.Offset) if err != nil { m.copyError = err return } } }
func (d *Discoverer) externalLookup(node string) []string { extIP, err := net.ResolveUDPAddr("udp", d.extServer) if err != nil { log.Printf("discover/external: %v; no external lookup", err) return nil } conn, err := net.DialUDP("udp", nil, extIP) if err != nil { log.Printf("discover/external: %v; no external lookup", err) return nil } defer conn.Close() err = conn.SetDeadline(time.Now().Add(5 * time.Second)) if err != nil { log.Printf("discover/external: %v; no external lookup", err) return nil } buf := QueryV2{QueryMagicV2, node}.MarshalXDR() _, err = conn.Write(buf) if err != nil { log.Printf("discover/external: %v; no external lookup", err) return nil } buffers.Put(buf) buf = buffers.Get(2048) defer buffers.Put(buf) n, err := conn.Read(buf) if err != nil { if err, ok := err.(net.Error); ok && err.Timeout() { // Expected if the server doesn't know about requested node ID return nil } log.Printf("discover/external/read: %v; no external lookup", err) return nil } if debug { dlog.Printf("read external:\n%s", hex.Dump(buf[:n])) } var pkt AnnounceV2 err = pkt.UnmarshalXDR(buf[:n]) if err != nil && err != io.EOF { log.Println("discover/external/decode:", err) return nil } if debug { dlog.Printf("parsed external: %#v", pkt) } var addrs []string for _, a := range pkt.This.Addresses { nodeAddr := fmt.Sprintf("%s:%d", net.IP(a.IP), a.Port) addrs = append(addrs, nodeAddr) } return addrs }