Когда я отправляю одноранговое сообщение с запросом на расширение, но не получаю ответа от одноранговых узлов.
Я получил рукопожатие и расширенное поле битов и Have Piece в порядке, но сообщения о расширении не получено.
Этомой код Голанга.
package main
import (
"bytes"
"crypto/rand"
"encoding/binary"
"fmt"
"github.com/IncSW/go-bencode"
"io"
"log"
"net"
"time"
)
func readBuffer(conn *net.TCPConn, size uint32) ([]byte, error) {
//temp := make([]byte, size)
//_, err := conn.Read(temp)
//if err != nil {
// return nil, fmt.Errorf("read %d bytes message failed: %v", size, err)
//}
//return temp, nil
buffer := bytes.NewBuffer(nil)
conn.SetReadDeadline(time.Now().Add(time.Second * 120))
_, err := io.CopyN(buffer, conn, int64(size))
if err != nil {
return nil, fmt.Errorf("read %d bytes message failed: %v", size, err)
}
return buffer.Bytes(), nil
}
func next(conn *net.TCPConn) ([]byte, error) {
buffer, err := readBuffer(conn, 4)
if nil != err {
return nil, err
}
buffer, err = readBuffer(conn, binary.BigEndian.Uint32(buffer))
if nil != err {
return nil, err
}
return buffer, nil
}
func getHandshake(infoHash []byte, nodeId []byte) []byte {
packet := []byte{19, 66, 105, 116, 84, 111, 114, 114, 101, 110, 116, 32, 112, 114, 111, 116, 111, 99, 111, 108, 0, 0, 0, 0, 0, 16, 0, 1}
packet = append(packet, infoHash...)
packet = append(packet, nodeId...)
return packet
}
// http://www.bittorrent.org/beps/bep_0009.html
// http://www.bittorrent.org/beps/bep_0010.html
func peerWire(addr string, infoHash []byte, nodeId []byte) {
dial, err := net.DialTimeout("tcp", addr, 10*time.Second)
if nil != err {
return
}
conn := dial.(*net.TCPConn)
conn.SetLinger(0)
defer conn.Close()
// handshake
handshake := getHandshake(infoHash, nodeId)
conn.Write(handshake)
handshakeRes := make([]byte, 68)
_, err = conn.Read(handshakeRes)
if !(bytes.Equal(handshake[:20], handshakeRes[:20]) && handshakeRes[25]&0x10 != 0) {
log.Println("invalid handshake response")
return
}
// extended handshake
// [length prefix][BitTorrent message ID][extended message ID]
extendedHandshake, _ := bencode.Marshal(map[string]interface{}{
"m": map[string]interface{}{"ut_metadata": 1},
})
extendedHandshake = append([]byte{20, 0}, extendedHandshake...)
size := make([]byte, 4)
extendedHandshake = append(size, extendedHandshake...)
conn.Write(extendedHandshake)
buffer, err := next(conn)
if nil != err {
log.Println(err.Error())
return
}
if 0 < len(buffer) {
msgUT, err := bencode.Unmarshal(buffer[2:])
if nil != err {
log.Println("error")
return
}
metadataSize, ok := msgUT.(map[string]interface{})["metadata_size"].(int64)
if !ok {
return
}
m, ok := msgUT.(map[string]interface{})["m"].(map[string]interface{})
if !ok {
return
}
utMetadata, ok := m["ut_metadata"].(int64)
if !ok {
return
}
numberOfPieces := metadataSize / 16384
if metadataSize%16384 != 0 {
numberOfPieces++
}
for i := 0; i < int(numberOfPieces); i++ {
packet, err := bencode.Marshal(map[string]interface{}{"msg_type":0, "piece":int(i)})
if nil != err {
log.Println(err)
}
packet = append([]byte{20, byte(utMetadata)}, packet...)
size := make([]byte, 4)
binary.BigEndian.PutUint32(size, uint32(len(packet)))
packet = append(size, packet...)
conn.Write(packet)
break
}
piece := make([]byte, 0)
for {
buffer, err := next(conn)
if nil != err {
log.Println(err.Error())
break
}
log.Println(buffer)
if 20 != buffer[0] {
continue
}
log.Println("buffer: ", buffer)
piece = append(piece, buffer...)
}
log.Println("index :", bytes.Index(piece, []byte("ee")))
}
}
func main() {
nodeId := make([]byte, 20)
rand.Read(nodeId)
infoHash := []byte{231, 130, 244, 163, 244, 122, 203, 232, 78, 218, 29, 116, 240, 232, 146, 236, 199, 72, 132, 254}
addr := "203.81.67.114:55254"
peerWire(addr, infoHash, nodeId)
}
Я думаю, что сообщение запроса расширения "[] байт {0, 0, 0, 27, 20, 2, 100, 53, 58, 112, 105, 101, 99,101, 105, 48, 101, 56, 58, 109, 115, 103, 95, 116, 121, 112, 101, 105, 48, 101, 101} "формат правильный.
![enter image description here](https://i.stack.imgur.com/dcgd8.png)
Данные дампа WireShark