Esempio n. 1
0
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
}
Esempio n. 2
0
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()
}