# Confusion regarding stage #XI4

**URL:** <https://forum.codecrafters.io/t/confusion-regarding-stage-xi4/2944>\
**Category:** Challenges\
**Tags:** challenge:bittorrent\
**Created:** [November 14, 2024, 8:00pm UTC](https://forum.codecrafters.io/t/confusion-regarding-stage-xi4/2944 "2024-11-14T20:00:29Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![TusharAbhinav](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/tusharabhinav/32/2754_2.png) [@TusharAbhinav](https://forum.codecrafters.io/u/TusharAbhinav)\
**Post date:** [November 14, 2024, 8:00pm UTC](https://forum.codecrafters.io/t/confusion-regarding-stage-xi4/2944/1 "2024-11-14T20:00:29Z")

</div>

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:

```goLang
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
	}
}

```

---

<div class="post-metadata">

**Author:** ![rohitpaulk](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/rohitpaulk/32/6_2.png) [@rohitpaulk](https://forum.codecrafters.io/u/rohitpaulk)\
**Post date:** [November 15, 2024, 9:32am UTC](https://forum.codecrafters.io/t/confusion-regarding-stage-xi4/2944/3 "2024-11-15T09:32:42Z")

</div>

@TusharAbhinav since BitTorrent is peer-to-peer, if both peers waited for each other to send the handshake, they’d just be deadlocked (neither would end up sending it, they’d just wait on each other). You should be able to safely send out your handshake that says that you support magnet links. Any peer that doesn’t support it will just ignore the reserved bits it doesn’t understand.

Could you try sending the handshake right away, and then waiting for the handshake back? I think that should work.

---

<div class="post-metadata">

**Author:** ![andy1li](https://yyz1.discourse-cdn.com/flex003/user_avatar/forum.codecrafters.io/andy1li/32/10_2.png) [@andy1li](https://forum.codecrafters.io/u/andy1li)\
**Post date:** [November 23, 2024, 2:34pm UTC](https://forum.codecrafters.io/t/confusion-regarding-stage-xi4/2944/5 "2024-11-23T14:34:28Z")

</div>

Closing this thread due to inactivity. If you still need assistance, feel free to reopen or start a new discussion!

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex003/uploads/codecrafters/original/3X/7/0/700657133935c15703e22c7c8870394f6e6dc27d.svg) [@system](https://forum.codecrafters.io/u/system)\
**Post date:** [November 28, 2024, 2:34pm UTC](https://forum.codecrafters.io/t/confusion-regarding-stage-xi4/2944/6 "2024-11-28T14:34:52Z")

</div>

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.
