Example #1
0
func ReadMessageOrTimeout(c *MockConnection, ctx C) (structure.Message, error) {
	select {
	case b := <-c.ReceiveBytesChan:
		m, err := structure.ReadMessage(bytes.NewReader(b))
		return m, err
	case <-time.After(time.Millisecond * 10):
		return nil, errors.New("Timeout")
	}
}
Example #2
0
func (btc *BTConn) readLoop(addChan, leaveChan chan<- *BTConn) {
	for {
		select {
		case _ = <-btc.HandshakeChan:
			log.Printf("[readLoop] Waiting for Handshake\n")
			peerHs, err := handleHandshake(btc)
			if err != nil {
				log.Printf("[readLoop] Error: %q", err.Error())
				btc.Close()
				leaveChan <- btc
				continue
			}

			log.Printf("[readLoop] State: %q", btc.State)

			switch btc.State {
			case BTStateWaitingForHandshake:
				log.Printf("[readLoop] HashMatch? %q === %q?", btc.Hash, string(peerHs.Hash))
				if btc.Hash != string(peerHs.Hash) {
					// TODO: What if same connection is handling multiple hashes?
					log.Printf("[readLoop] Hash mismatch\n")
					btc.Close()
					leaveChan <- btc
					continue
				}
			case BTStateStartListening:
				log.Printf("Writing byte %q\n", btc)
				respHs, err := structure.NewHandshake(peerHs.Hash, []byte(btc.PeerID))
				log.Println("[readLoop] respHS ", respHs)
				if err != nil {
					log.Printf("[readLoop] %q\n", err.Error())
					btc.Close()
					leaveChan <- btc
					continue
				}
				btc.Write(respHs.Bytes())
			default:
				log.Printf("[readLoop] BAD STATE: %d", btc.State)
				btc.Close()
				leaveChan <- btc
				continue
			}

			addChan <- btc
			log.Printf("AAAAAAAAAAAAAAAAAAAAAAAA: %q", btc.Addr)
			btc.State = BTStateReadyForMessages
			btc.MessageChan <- true
		case _ = <-btc.MessageChan:
			log.Printf("[readLoop] Reading from MessageChan: %q", btc)
			m, err := structure.ReadMessage(btc)
			if err != nil {
				log.Printf("[readLoop] Error reading message: %s", err)
				btc.Close()
				leaveChan <- btc
				continue
			}
			log.Printf("[readLoop] Did Read from MessageChan: %q", m)

			switch m.(type) {
			case *structure.KeepAliveMessage:
				log.Println("[readLoop] Received: KeepAlive MESSAGE")
				// TODO: reset disconnect timer
				break
			case *structure.ChokeMessage:
				break
			case *structure.UnchokeMessage:
				log.Println("[readLoop] Received: Unchoke MESSAGE")
				btc.PeerChoking = false
				btc.WriteChan <- structure.NewRequestMessage(0x00000bb0, 0x00024000, 0x00004000)
			case *structure.BitFieldMessage:
				log.Println("[readLoop] Received: Bit Field MESSAGE")
				btc.BitField = m.(*structure.BitFieldMessage).BitField
				btc.WriteChan <- structure.NewInterestedMessage()
			case *structure.HaveMessage:
				log.Println("[readLoop] Received: Have MESSAGE")
				pi := m.(*structure.HaveMessage).PieceIndex
				log.Printf("[readLoop] Have Message Index: %q", pi)
				log.Printf("BIT 0: %q", btc.BitField.Get(0))
				btc.BitField.Set(uint32(pi), 1)
				log.Printf("BIT 0: %q", btc.BitField.Get(0))

			//			case *structure.PieceMessage:
			//				log.Println("[readLoop] Received: Piece MESSAGE")
			default:
				log.Println("[readLoop] Received: OTHER MESSAGE")
			}
			log.Println("[readLoop] Received Message: ", m)
			btc.MessageChan <- true
		}
	}
}