event sync.Cond
        quit  chan struct{}
 
-       halfOpen int
-       torrents map[InfoHash]*torrent
+       halfOpen    int
+       handshaking int
+       torrents    map[InfoHash]*torrent
 
        dataWaiterMutex sync.Mutex
        dataWaiter      chan struct{}
        }
        fmt.Fprintf(w, "Peer ID: %q\n", cl.peerID)
        fmt.Fprintf(w, "Half open outgoing connections: %d\n", cl.halfOpen)
+       fmt.Fprintf(w, "Handshaking: %d\n", cl.handshaking)
        if cl.dHT != nil {
                fmt.Fprintf(w, "DHT nodes: %d\n", cl.dHT.NumNodes())
                fmt.Fprintf(w, "DHT Server ID: %x\n", cl.dHT.IDString())
        return
 }
 
+type peerConn struct {
+       net.Conn
+}
+
+func (pc peerConn) Read(b []byte) (n int, err error) {
+       err = pc.Conn.SetReadDeadline(time.Now().Add(150 * time.Second))
+       if err != nil {
+               return
+       }
+       n, err = pc.Conn.Read(b)
+       return
+}
+
 func (me *Client) runConnection(sock net.Conn, torrent *torrent, discovery peerSource) (err error) {
        defer sock.Close()
+       me.mu.Lock()
+       me.handshaking++
+       me.mu.Unlock()
+       // One minute to complete handshake.
+       sock.SetDeadline(time.Now().Add(time.Minute))
        hsRes, ok, err := handshake(sock, func() *InfoHash {
                if torrent == nil {
                        return nil
                        return &torrent.InfoHash
                }
        }(), me.peerID)
+       me.mu.Lock()
+       defer me.mu.Unlock()
+       if me.handshaking == 0 {
+               panic("handshake count invariant is broken")
+       }
+       me.handshaking--
        if err != nil {
                err = fmt.Errorf("error during handshake: %s", err)
                return
        if !ok {
                return
        }
-       me.mu.Lock()
-       defer me.mu.Unlock()
        torrent = me.torrent(hsRes.InfoHash)
        if torrent == nil {
                return
        }
+       sock.SetWriteDeadline(time.Time{})
+       sock = peerConn{sock}
        conn := newConnection(sock, hsRes.peerExtensionBytes, hsRes.peerID)
        defer conn.Close()
        conn.Discovery = discovery