package peer import "io" // Messages const ( Choke = iota // choke: Unchoke // unchoke: Interested // interested: NotInterested // not interested: Have // have: BitField // bitfield: Request // request: Piece // piece: Cancel // cancel: Port // port: DHT _ // keep-alive: _ _ Suggset HaveAll HaveNone Reject AllowedFast _ _ LTEPHandshake ) const Proto = `BitTorrent protocol` type Handshake struct { Proto string Flags [8]byte InfoHash [20]byte PeerID [20]byte } func (h Handshake) Encode(w io.Writer) { Frame(w, []byte(h.Proto)) w.Write(h.Flags[:]) w.Write(h.InfoHash[:]) w.Write(h.PeerID[:]) } func DecodeHandshake(r io.Reader) (Handshake, bool) { var h Handshake h.Proto = string(Deframe(r)) if h.Proto != Proto { return h, false } r.Read(h.Flags[:]) r.Read(h.InfoHash[:]) r.Read(h.PeerID[:]) return h, true } func Frame(w io.Writer, b []byte) { l := len(b) w.Write([]byte{byte(l)}) w.Write(b) } func Deframe(r io.Reader) []byte { l := make([]byte, 1) r.Read(l) if sz := int(l[0]); sz > 0 { b := make([]byte, sz) r.Read(b) return b } return nil }