You've already forked torrent-client
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:
60
handshake/handshake.go
Normal file
60
handshake/handshake.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user