func (c *OneConnection) SendPendingData() bool { if c.SendBufProd != c.SendBufCons { bytes_to_send := c.SendBufProd - c.SendBufCons if bytes_to_send < 0 { bytes_to_send += SendBufSize } if c.SendBufCons+bytes_to_send > SendBufSize { bytes_to_send = SendBufSize - c.SendBufCons } n, e := common.SockWrite(c.Conn, c.sendBuf[c.SendBufCons:c.SendBufCons+bytes_to_send]) if n > 0 { c.Mutex.Lock() c.X.LastSent = time.Now() c.X.BytesSent += uint64(n) n += c.SendBufCons if n >= SendBufSize { c.SendBufCons = 0 } else { c.SendBufCons = n } c.Mutex.Unlock() } else if time.Now().After(c.X.LastSent.Add(AnySendTimeout)) { common.CountSafe("PeerSendTimeout") c.Disconnect() } else if e != nil { if common.DebugLevel > 0 { println(c.PeerAddr.Ip(), "Connection Broken during send") } c.Disconnect() } } return c.SendBufProd != c.SendBufCons }
func (c *OneConnection) Tick() { c.Mutex.Lock() c.TicksCnt++ c.Mutex.Unlock() // Disconnect and ban useless peers (sych that don't send invs) if c.InvsRecieved == 0 && c.ConnectedAt.Add(15*time.Minute).Before(time.Now()) { common.CountSafe("NetUselessPeer") c.DoS() return } // Check no-data timeout if c.LastDataGot.Add(NoDataTimeout).Before(time.Now()) { c.Disconnect() common.CountSafe("NetNodataTout") if common.DebugLevel > 0 { println(c.PeerAddr.Ip(), "no data for", NoDataTimeout/time.Second, "seconds - disconnect") } return } if c.Send.Buf != nil { n, e := common.SockWrite(c.NetConn, c.Send.Buf) if n > 0 { c.Mutex.Lock() c.Send.LastSent = time.Now() c.BytesSent += uint64(n) if n >= len(c.Send.Buf) { c.Send.Buf = nil } else { tmp := make([]byte, len(c.Send.Buf)-n) copy(tmp, c.Send.Buf[n:]) c.Send.Buf = tmp } c.Mutex.Unlock() } else if time.Now().After(c.Send.LastSent.Add(AnySendTimeout)) { common.CountSafe("PeerSendTimeout") c.Disconnect() } else if e != nil { if common.DebugLevel > 0 { println(c.PeerAddr.Ip(), "Connection Broken during send") } c.Disconnect() } return } if !c.VerackReceived { // If we have no ack, do nothing more. return } // Ask node for new addresses...? if time.Now().After(c.NextGetAddr) { if PeerDB.Count() > common.MaxPeersNeeded { // If we have a lot of peers, do not ask for more, to save bandwidth common.CountSafe("AddrEnough") } else { common.CountSafe("AddrWanted") c.SendRawMsg("getaddr", nil) } c.NextGetAddr = time.Now().Add(AskAddrsEvery) return } // Need to send some invs...? if c.SendInvs() { return } // Timeout getdata for blocks in progress, so the map does not grow to infinity for k, v := range c.GetBlockInProgress { if time.Now().After(v.start.Add(GetBlockTimeout)) { common.CountSafe("GetBlockTimeout") c.Mutex.Lock() delete(c.GetBlockInProgress, k) c.Mutex.Unlock() } } // Need to send getblocks...? if len(c.GetBlockInProgress) == 0 && c.getblocksNeeded() { return } // Ping if we dont do anything c.TryPing() }