You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

620 lines
16 KiB

11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package p2p
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "math"
  7. "net"
  8. "runtime/debug"
  9. "sync/atomic"
  10. "time"
  11. flow "code.google.com/p/mxk/go1/flowcontrol"
  12. //"github.com/tendermint/log15"
  13. "github.com/tendermint/tendermint/binary"
  14. . "github.com/tendermint/tendermint/common"
  15. )
  16. const (
  17. numBatchMsgPackets = 10
  18. minReadBufferSize = 1024
  19. minWriteBufferSize = 1024
  20. flushThrottleMS = 50
  21. idleTimeoutMinutes = 5
  22. updateStatsSeconds = 2
  23. pingTimeoutMinutes = 2
  24. defaultSendRate = 51200 // 5Kb/s
  25. defaultRecvRate = 51200 // 5Kb/s
  26. defaultSendQueueCapacity = 1
  27. defaultRecvBufferCapacity = 4096
  28. defaultSendTimeoutSeconds = 10
  29. )
  30. type receiveCbFunc func(chId byte, msgBytes []byte)
  31. type errorCbFunc func(interface{})
  32. /*
  33. Each peer has one `MConnection` (multiplex connection) instance.
  34. __multiplex__ *noun* a system or signal involving simultaneous transmission of
  35. several messages along a single channel of communication.
  36. Each `MConnection` handles message transmission on multiple abstract communication
  37. `Channel`s. Each channel has a globally unique byte id.
  38. The byte id and the relative priorities of each `Channel` are configured upon
  39. initialization of the connection.
  40. There are two methods for sending messages:
  41. func (m MConnection) Send(chId byte, msg interface{}) bool {}
  42. func (m MConnection) TrySend(chId byte, msg interface{}) bool {}
  43. `Send(chId, msg)` is a blocking call that waits until `msg` is successfully queued
  44. for the channel with the given id byte `chId`, or until the request times out.
  45. The message `msg` is serialized using the `tendermint/binary` submodule's
  46. `WriteBinary()` reflection routine.
  47. `TrySend(chId, msg)` is a nonblocking call that returns false if the channel's
  48. queue is full.
  49. Inbound message bytes are handled with an onReceive callback function.
  50. */
  51. type MConnection struct {
  52. conn net.Conn
  53. bufReader *bufio.Reader
  54. bufWriter *bufio.Writer
  55. sendMonitor *flow.Monitor
  56. recvMonitor *flow.Monitor
  57. sendRate int64
  58. recvRate int64
  59. flushTimer *ThrottleTimer // flush writes as necessary but throttled.
  60. send chan struct{}
  61. quit chan struct{}
  62. pingTimer *RepeatTimer // send pings periodically
  63. pong chan struct{}
  64. chStatsTimer *RepeatTimer // update channel stats periodically
  65. channels []*Channel
  66. channelsIdx map[byte]*Channel
  67. onReceive receiveCbFunc
  68. onError errorCbFunc
  69. started uint32
  70. stopped uint32
  71. errored uint32
  72. LocalAddress *NetAddress
  73. RemoteAddress *NetAddress
  74. }
  75. func NewMConnection(conn net.Conn, chDescs []*ChannelDescriptor, onReceive receiveCbFunc, onError errorCbFunc) *MConnection {
  76. mconn := &MConnection{
  77. conn: conn,
  78. bufReader: bufio.NewReaderSize(conn, minReadBufferSize),
  79. bufWriter: bufio.NewWriterSize(conn, minWriteBufferSize),
  80. sendMonitor: flow.New(0, 0),
  81. recvMonitor: flow.New(0, 0),
  82. sendRate: defaultSendRate,
  83. recvRate: defaultRecvRate,
  84. flushTimer: NewThrottleTimer("flush", flushThrottleMS*time.Millisecond),
  85. send: make(chan struct{}, 1),
  86. quit: make(chan struct{}),
  87. pingTimer: NewRepeatTimer("ping", pingTimeoutMinutes*time.Minute),
  88. pong: make(chan struct{}),
  89. chStatsTimer: NewRepeatTimer("chStats", updateStatsSeconds*time.Second),
  90. onReceive: onReceive,
  91. onError: onError,
  92. LocalAddress: NewNetAddress(conn.LocalAddr()),
  93. RemoteAddress: NewNetAddress(conn.RemoteAddr()),
  94. }
  95. // Create channels
  96. var channelsIdx = map[byte]*Channel{}
  97. var channels = []*Channel{}
  98. for _, desc := range chDescs {
  99. channel := newChannel(mconn, desc)
  100. channelsIdx[channel.id] = channel
  101. channels = append(channels, channel)
  102. }
  103. mconn.channels = channels
  104. mconn.channelsIdx = channelsIdx
  105. return mconn
  106. }
  107. // .Start() begins multiplexing packets to and from "channels".
  108. func (c *MConnection) Start() {
  109. if atomic.CompareAndSwapUint32(&c.started, 0, 1) {
  110. log.Debug("Starting MConnection", "connection", c)
  111. go c.sendRoutine()
  112. go c.recvRoutine()
  113. }
  114. }
  115. func (c *MConnection) Stop() {
  116. if atomic.CompareAndSwapUint32(&c.stopped, 0, 1) {
  117. log.Debug("Stopping MConnection", "connection", c)
  118. close(c.quit)
  119. c.conn.Close()
  120. c.flushTimer.Stop()
  121. c.chStatsTimer.Stop()
  122. c.pingTimer.Stop()
  123. // We can't close pong safely here because
  124. // recvRoutine may write to it after we've stopped.
  125. // Though it doesn't need to get closed at all,
  126. // we close it @ recvRoutine.
  127. // close(c.pong)
  128. }
  129. }
  130. func (c *MConnection) String() string {
  131. return fmt.Sprintf("MConn{%v}", c.conn.RemoteAddr())
  132. }
  133. func (c *MConnection) flush() {
  134. err := c.bufWriter.Flush()
  135. if err != nil {
  136. if atomic.LoadUint32(&c.stopped) != 1 {
  137. log.Warn("MConnection flush failed", "error", err)
  138. }
  139. }
  140. }
  141. // Catch panics, usually caused by remote disconnects.
  142. func (c *MConnection) _recover() {
  143. if r := recover(); r != nil {
  144. stack := debug.Stack()
  145. err := StackError{r, stack}
  146. c.stopForError(err)
  147. }
  148. }
  149. func (c *MConnection) stopForError(r interface{}) {
  150. c.Stop()
  151. if atomic.CompareAndSwapUint32(&c.errored, 0, 1) {
  152. if c.onError != nil {
  153. c.onError(r)
  154. }
  155. }
  156. }
  157. // Queues a message to be sent to channel.
  158. func (c *MConnection) Send(chId byte, msg interface{}) bool {
  159. if atomic.LoadUint32(&c.stopped) == 1 {
  160. return false
  161. }
  162. log.Debug("Send", "channel", chId, "connection", c, "msg", msg) //, "bytes", binary.BinaryBytes(msg))
  163. // Send message to channel.
  164. channel, ok := c.channelsIdx[chId]
  165. if !ok {
  166. log.Error(Fmt("Cannot send bytes, unknown channel %X", chId))
  167. return false
  168. }
  169. success := channel.sendBytes(binary.BinaryBytes(msg))
  170. // Wake up sendRoutine if necessary
  171. select {
  172. case c.send <- struct{}{}:
  173. default:
  174. }
  175. return success
  176. }
  177. // Queues a message to be sent to channel.
  178. // Nonblocking, returns true if successful.
  179. func (c *MConnection) TrySend(chId byte, msg interface{}) bool {
  180. if atomic.LoadUint32(&c.stopped) == 1 {
  181. return false
  182. }
  183. log.Debug("TrySend", "channel", chId, "connection", c, "msg", msg)
  184. // Send message to channel.
  185. channel, ok := c.channelsIdx[chId]
  186. if !ok {
  187. log.Error(Fmt("Cannot send bytes, unknown channel %X", chId))
  188. return false
  189. }
  190. ok = channel.trySendBytes(binary.BinaryBytes(msg))
  191. if ok {
  192. // Wake up sendRoutine if necessary
  193. select {
  194. case c.send <- struct{}{}:
  195. default:
  196. }
  197. }
  198. return ok
  199. }
  200. func (c *MConnection) CanSend(chId byte) bool {
  201. if atomic.LoadUint32(&c.stopped) == 1 {
  202. return false
  203. }
  204. channel, ok := c.channelsIdx[chId]
  205. if !ok {
  206. log.Error(Fmt("Unknown channel %X", chId))
  207. return false
  208. }
  209. return channel.canSend()
  210. }
  211. // sendRoutine polls for packets to send from channels.
  212. func (c *MConnection) sendRoutine() {
  213. defer c._recover()
  214. FOR_LOOP:
  215. for {
  216. var n int64
  217. var err error
  218. select {
  219. case <-c.flushTimer.Ch:
  220. // NOTE: flushTimer.Set() must be called every time
  221. // something is written to .bufWriter.
  222. c.flush()
  223. case <-c.chStatsTimer.Ch:
  224. for _, channel := range c.channels {
  225. channel.updateStats()
  226. }
  227. case <-c.pingTimer.Ch:
  228. log.Debug("Send Ping")
  229. binary.WriteByte(packetTypePing, c.bufWriter, &n, &err)
  230. c.sendMonitor.Update(int(n))
  231. c.flush()
  232. case <-c.pong:
  233. log.Debug("Send Pong")
  234. binary.WriteByte(packetTypePong, c.bufWriter, &n, &err)
  235. c.sendMonitor.Update(int(n))
  236. c.flush()
  237. case <-c.quit:
  238. break FOR_LOOP
  239. case <-c.send:
  240. // Send some msgPackets
  241. eof := c.sendSomeMsgPackets()
  242. if !eof {
  243. // Keep sendRoutine awake.
  244. select {
  245. case c.send <- struct{}{}:
  246. default:
  247. }
  248. }
  249. }
  250. if atomic.LoadUint32(&c.stopped) == 1 {
  251. break FOR_LOOP
  252. }
  253. if err != nil {
  254. log.Warn("Connection failed @ sendRoutine", "connection", c, "error", err)
  255. c.stopForError(err)
  256. break FOR_LOOP
  257. }
  258. }
  259. // Cleanup
  260. }
  261. // Returns true if messages from channels were exhausted.
  262. // Blocks in accordance to .sendMonitor throttling.
  263. func (c *MConnection) sendSomeMsgPackets() bool {
  264. // Block until .sendMonitor says we can write.
  265. // Once we're ready we send more than we asked for,
  266. // but amortized it should even out.
  267. c.sendMonitor.Limit(maxMsgPacketSize, atomic.LoadInt64(&c.sendRate), true)
  268. // Now send some msgPackets.
  269. for i := 0; i < numBatchMsgPackets; i++ {
  270. if c.sendMsgPacket() {
  271. return true
  272. }
  273. }
  274. return false
  275. }
  276. // Returns true if messages from channels were exhausted.
  277. func (c *MConnection) sendMsgPacket() bool {
  278. // Choose a channel to create a msgPacket from.
  279. // The chosen channel will be the one whose recentlySent/priority is the least.
  280. var leastRatio float32 = math.MaxFloat32
  281. var leastChannel *Channel
  282. for _, channel := range c.channels {
  283. // If nothing to send, skip this channel
  284. if !channel.isSendPending() {
  285. continue
  286. }
  287. // Get ratio, and keep track of lowest ratio.
  288. ratio := float32(channel.recentlySent) / float32(channel.priority)
  289. if ratio < leastRatio {
  290. leastRatio = ratio
  291. leastChannel = channel
  292. }
  293. }
  294. // Nothing to send?
  295. if leastChannel == nil {
  296. return true
  297. } else {
  298. // log.Debug("Found a msgPacket to send")
  299. }
  300. // Make & send a msgPacket from this channel
  301. n, err := leastChannel.writeMsgPacketTo(c.bufWriter)
  302. if err != nil {
  303. log.Warn("Failed to write msgPacket", "error", err)
  304. c.stopForError(err)
  305. return true
  306. }
  307. c.sendMonitor.Update(int(n))
  308. c.flushTimer.Set()
  309. return false
  310. }
  311. // recvRoutine reads msgPackets and reconstructs the message using the channels' "recving" buffer.
  312. // After a whole message has been assembled, it's pushed to onReceive().
  313. // Blocks depending on how the connection is throttled.
  314. func (c *MConnection) recvRoutine() {
  315. defer c._recover()
  316. FOR_LOOP:
  317. for {
  318. // Block until .recvMonitor says we can read.
  319. c.recvMonitor.Limit(maxMsgPacketSize, atomic.LoadInt64(&c.recvRate), true)
  320. /*
  321. // Peek into bufReader for debugging
  322. if numBytes := c.bufReader.Buffered(); numBytes > 0 {
  323. log.Debug("Peek connection buffer", "numBytes", numBytes, "bytes", log15.Lazy{func() []byte {
  324. bytes, err := c.bufReader.Peek(MinInt(numBytes, 100))
  325. if err == nil {
  326. return bytes
  327. } else {
  328. log.Warn("Error peeking connection buffer", "error", err)
  329. return nil
  330. }
  331. }})
  332. }
  333. */
  334. // Read packet type
  335. var n int64
  336. var err error
  337. pktType := binary.ReadByte(c.bufReader, &n, &err)
  338. c.recvMonitor.Update(int(n))
  339. if err != nil {
  340. if atomic.LoadUint32(&c.stopped) != 1 {
  341. log.Warn("Connection failed @ recvRoutine (reading byte)", "connection", c, "error", err)
  342. c.stopForError(err)
  343. }
  344. break FOR_LOOP
  345. }
  346. // Read more depending on packet type.
  347. switch pktType {
  348. case packetTypePing:
  349. // TODO: prevent abuse, as they cause flush()'s.
  350. log.Debug("Receive Ping")
  351. c.pong <- struct{}{}
  352. case packetTypePong:
  353. // do nothing
  354. log.Debug("Receive Pong")
  355. case packetTypeMsg:
  356. pkt, n, err := msgPacket{}, new(int64), new(error)
  357. binary.ReadBinary(&pkt, c.bufReader, n, err)
  358. c.recvMonitor.Update(int(*n))
  359. if *err != nil {
  360. if atomic.LoadUint32(&c.stopped) != 1 {
  361. log.Warn("Connection failed @ recvRoutine", "connection", c, "error", *err)
  362. c.stopForError(*err)
  363. }
  364. break FOR_LOOP
  365. }
  366. channel, ok := c.channelsIdx[pkt.ChannelId]
  367. if !ok || channel == nil {
  368. panic(Fmt("Unknown channel %X", pkt.ChannelId))
  369. }
  370. msgBytes := channel.recvMsgPacket(pkt)
  371. if msgBytes != nil {
  372. //log.Debug("Received bytes", "chId", pkt.ChannelId, "msgBytes", msgBytes)
  373. c.onReceive(pkt.ChannelId, msgBytes)
  374. }
  375. default:
  376. panic(Fmt("Unknown message type %X", pktType))
  377. }
  378. // TODO: shouldn't this go in the sendRoutine?
  379. // Better to send a ping packet when *we* haven't sent anything for a while.
  380. c.pingTimer.Reset()
  381. }
  382. // Cleanup
  383. close(c.pong)
  384. for _ = range c.pong {
  385. // Drain
  386. }
  387. }
  388. //-----------------------------------------------------------------------------
  389. type ChannelDescriptor struct {
  390. Id byte
  391. Priority uint
  392. SendQueueCapacity uint
  393. RecvBufferCapacity uint
  394. }
  395. func (chDesc *ChannelDescriptor) FillDefaults() {
  396. if chDesc.SendQueueCapacity == 0 {
  397. chDesc.SendQueueCapacity = defaultSendQueueCapacity
  398. }
  399. if chDesc.RecvBufferCapacity == 0 {
  400. chDesc.RecvBufferCapacity = defaultRecvBufferCapacity
  401. }
  402. }
  403. // TODO: lowercase.
  404. // NOTE: not goroutine-safe.
  405. type Channel struct {
  406. conn *MConnection
  407. desc *ChannelDescriptor
  408. id byte
  409. sendQueue chan []byte
  410. sendQueueSize uint32 // atomic.
  411. recving []byte
  412. sending []byte
  413. priority uint
  414. recentlySent int64 // exponential moving average
  415. }
  416. func newChannel(conn *MConnection, desc *ChannelDescriptor) *Channel {
  417. desc.FillDefaults()
  418. if desc.Priority <= 0 {
  419. panic("Channel default priority must be a postive integer")
  420. }
  421. return &Channel{
  422. conn: conn,
  423. desc: desc,
  424. id: desc.Id,
  425. sendQueue: make(chan []byte, desc.SendQueueCapacity),
  426. recving: make([]byte, 0, desc.RecvBufferCapacity),
  427. priority: desc.Priority,
  428. }
  429. }
  430. // Queues message to send to this channel.
  431. // Goroutine-safe
  432. // Times out (and returns false) after defaultSendTimeoutSeconds
  433. func (ch *Channel) sendBytes(bytes []byte) bool {
  434. sendTicker := time.NewTicker(defaultSendTimeoutSeconds * time.Second)
  435. select {
  436. case <-sendTicker.C:
  437. // timeout
  438. return false
  439. case ch.sendQueue <- bytes:
  440. atomic.AddUint32(&ch.sendQueueSize, 1)
  441. return true
  442. }
  443. }
  444. // Queues message to send to this channel.
  445. // Nonblocking, returns true if successful.
  446. // Goroutine-safe
  447. func (ch *Channel) trySendBytes(bytes []byte) bool {
  448. select {
  449. case ch.sendQueue <- bytes:
  450. atomic.AddUint32(&ch.sendQueueSize, 1)
  451. return true
  452. default:
  453. return false
  454. }
  455. }
  456. // Goroutine-safe
  457. func (ch *Channel) loadSendQueueSize() (size int) {
  458. return int(atomic.LoadUint32(&ch.sendQueueSize))
  459. }
  460. // Goroutine-safe
  461. // Use only as a heuristic.
  462. func (ch *Channel) canSend() bool {
  463. return ch.loadSendQueueSize() < defaultSendQueueCapacity
  464. }
  465. // Returns true if any msgPackets are pending to be sent.
  466. // Call before calling nextMsgPacket()
  467. // Goroutine-safe
  468. func (ch *Channel) isSendPending() bool {
  469. if len(ch.sending) == 0 {
  470. if len(ch.sendQueue) == 0 {
  471. return false
  472. }
  473. ch.sending = <-ch.sendQueue
  474. }
  475. return true
  476. }
  477. // Creates a new msgPacket to send.
  478. // Not goroutine-safe
  479. func (ch *Channel) nextMsgPacket() msgPacket {
  480. packet := msgPacket{}
  481. packet.ChannelId = byte(ch.id)
  482. packet.Bytes = ch.sending[:MinInt(maxMsgPacketSize, len(ch.sending))]
  483. if len(ch.sending) <= maxMsgPacketSize {
  484. packet.EOF = byte(0x01)
  485. ch.sending = nil
  486. atomic.AddUint32(&ch.sendQueueSize, ^uint32(0)) // decrement sendQueueSize
  487. } else {
  488. packet.EOF = byte(0x00)
  489. ch.sending = ch.sending[MinInt(maxMsgPacketSize, len(ch.sending)):]
  490. }
  491. return packet
  492. }
  493. // Writes next msgPacket to w.
  494. // Not goroutine-safe
  495. func (ch *Channel) writeMsgPacketTo(w io.Writer) (n int64, err error) {
  496. packet := ch.nextMsgPacket()
  497. binary.WriteByte(packetTypeMsg, w, &n, &err)
  498. binary.WriteBinary(packet, w, &n, &err)
  499. if err != nil {
  500. ch.recentlySent += n
  501. }
  502. return
  503. }
  504. // Handles incoming msgPackets. Returns a msg bytes if msg is complete.
  505. // Not goroutine-safe
  506. func (ch *Channel) recvMsgPacket(pkt msgPacket) []byte {
  507. ch.recving = append(ch.recving, pkt.Bytes...)
  508. if pkt.EOF == byte(0x01) {
  509. msgBytes := ch.recving
  510. ch.recving = make([]byte, 0, defaultRecvBufferCapacity)
  511. return msgBytes
  512. }
  513. return nil
  514. }
  515. // Call this periodically to update stats for throttling purposes.
  516. // Not goroutine-safe
  517. func (ch *Channel) updateStats() {
  518. // Exponential decay of stats.
  519. // TODO: optimize.
  520. ch.recentlySent = int64(float64(ch.recentlySent) * 0.5)
  521. }
  522. //-----------------------------------------------------------------------------
  523. const (
  524. maxMsgPacketSize = 1024
  525. packetTypePing = byte(0x01)
  526. packetTypePong = byte(0x02)
  527. packetTypeMsg = byte(0x03)
  528. )
  529. // Messages in channels are chopped into smaller msgPackets for multiplexing.
  530. type msgPacket struct {
  531. ChannelId byte
  532. EOF byte // 1 means message ends here.
  533. Bytes []byte
  534. }
  535. func (p msgPacket) String() string {
  536. return fmt.Sprintf("MsgPacket{%X:%X}", p.ChannelId, p.Bytes)
  537. }
  538. //-----------------------------------------------------------------------------
  539. // Convenience struct for writing typed messages.
  540. // Reading requires a custom decoder that switches on the first type byte of a byteslice.
  541. type TypedMessage struct {
  542. Type byte
  543. Msg interface{}
  544. }
  545. func (tm TypedMessage) String() string {
  546. return fmt.Sprintf("TMsg{%X:%v}", tm.Type, tm.Msg)
  547. }