I am bit confused about stage X14 aren’t we supposed to wait for base handshake message so that we can verify if the other peers supoort magnet links or not,When i am trying to wait for the handshake message,time limit exceeds and if i comment that code ,test case passes.
And here’s a snippet of my code:
func MagnetHandshake(magnetLink string) {
trackerURL, infoHash := ParseMagnetLinks(magnetLink)
byteInfoHash, _ := hex.DecodeString(infoHash)
var infoHashArray [20]byte
copy(infoHashArray[:], byteInfoHash)
peerList, err := peers.FetchPeersFromTracker(trackerURL, infoHashArray, nil)
if err != nil || len(peerList) == 0 {
fmt.Println("Error fetching peers or no peers available:", err)
return
}
peerTCPAddr, err := net.ResolveTCPAddr("tcp", peerList[0])
if err != nil {
fmt.Println("Error resolving TCP address:", err)
return
}
tcpConn, err := net.DialTCP("tcp", nil, peerTCPAddr)
if err != nil {
fmt.Println("Error establishing TCP connection:", err)
return
}
defer tcpConn.Close()
peerID := tcp.CompleteHandshake(tcpConn, infoHashArray)
fmt.Println("Peer ID:", peerID)
sendExtensionHandshake(tcpConn)
}
func sendExtensionHandshake(tcpConn *net.TCPConn) {
//uncommenting this fails the test with time limit exceeded
// fmt.Println("Attempting to read recieved handshake...")
// recievedHandShakeBuff := make([]byte, 68)
// _, err := io.ReadFull(tcpConn, recievedHandShakeBuff)
// if err != nil {
// fmt.Println("Error receiving handshake:", err)
// return
// }
// fmt.Println("1")
// reservedBytes := recievedHandShakeBuff[20:28]
// reserve := binary.BigEndian.Uint64(reservedBytes[:])
// mask := uint64(1) << 20
// if reserve&mask == 0 {
// fmt.Println("Peer does not support extension protocol")
// return
// }
for {
messageLength := make([]byte, 4)
_, err := io.ReadFull(tcpConn, messageLength)
if err != nil {
fmt.Println("Error reading message length:", err)
return
}
length := binary.BigEndian.Uint32(messageLength)
if length == 0 {
fmt.Println("Keep alive message received")
continue
}
messageID := make([]byte, 1)
_, err = io.ReadFull(tcpConn, messageID)
if err != nil {
fmt.Println("Error reading message ID:", err)
return
}
id := uint8(messageID[0])
switch id {
case 5:
fmt.Println("Received bitfield message")
payload := make([]byte, length-1)
_, err := io.ReadFull(tcpConn, payload)
if err != nil {
fmt.Println("Error reading bitfield payload:", err)
return
}
bencodedDict := map[string]interface{}{
"m": map[string]uint8{"ut_metadata": 20},
}
var bencodedDictBytesBuffer bytes.Buffer
err = bencode.Marshal(&bencodedDictBytesBuffer, bencodedDict)
if err != nil {
fmt.Println("Error encoding bencoded dictionary:", err)
return
}
extensionPayload := bencodedDictBytesBuffer.Bytes()
messageLen := len(extensionPayload) + 2
extensionHandshake := make([]byte, 4+messageLen)
binary.BigEndian.PutUint32(extensionHandshake[0:4], uint32(messageLen))
extensionHandshake[4] = 20
extensionHandshake[5] = 0
copy(extensionHandshake[6:], extensionPayload)
fmt.Println("Sending extension handshake...")
_, err = tcpConn.Write(extensionHandshake)
if err != nil {
fmt.Println("Error sending extension handshake:", err)
}
}
break
}
}