1
0
mirror of https://github.com/veggiedefender/torrent-client.git synced 2025-11-06 09:29:16 +02:00

Move handshake into its own package

This commit is contained in:
Jesse Li
2019-12-24 10:39:22 -05:00
parent aa8ef0ed76
commit c20965ebf5
5 changed files with 18 additions and 17 deletions

60
handshake/handshake.go Normal file
View File

@@ -0,0 +1,60 @@
package handshake
import (
"errors"
"io"
)
// A Handshake is a sequence of bytes a peer uses to identify itself
type Handshake struct {
Pstr string
InfoHash [20]byte
PeerID [20]byte
}
// Serialize serializes the handshake to a buffer
func (h *Handshake) Serialize() []byte {
pstrlen := len(h.Pstr)
bufLen := 49 + pstrlen
buf := make([]byte, bufLen)
buf[0] = byte(pstrlen)
copy(buf[1:], h.Pstr)
// Leave 8 reserved bytes
copy(buf[1+pstrlen+8:], h.InfoHash[:])
copy(buf[1+pstrlen+8+20:], h.PeerID[:])
return buf
}
// Read parses a message from a stream. Returns `nil` on keep-alive message
func Read(r io.Reader) (*Handshake, error) {
lengthBuf := make([]byte, 1)
_, err := io.ReadFull(r, lengthBuf)
if err != nil {
return nil, err
}
pstrlen := int(lengthBuf[0])
if pstrlen == 0 {
err := errors.New("pstrlen cannot be 0")
return nil, err
}
handshakeBuf := make([]byte, 48+pstrlen)
_, err = io.ReadFull(r, handshakeBuf)
if err != nil {
return nil, err
}
var infoHash, peerID [20]byte
copy(infoHash[:], handshakeBuf[pstrlen+8:pstrlen+8+20])
copy(peerID[:], handshakeBuf[pstrlen+8+20:])
h := Handshake{
Pstr: string(handshakeBuf[0:pstrlen]),
InfoHash: infoHash,
PeerID: peerID,
}
return &h, nil
}