aboutsummaryrefslogtreecommitdiffstats
path: root/peer.go
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-01-10 06:15:51 +0800
committerobscuren <geffobscura@gmail.com>2014-01-10 06:15:51 +0800
commit849408dda60fe32d7abb78d103b09ca0bc7b5a60 (patch)
treeb066b834e8e7b2182977fc9f784c821fad47e380 /peer.go
parent01740695cda7fe27c53f0fa078732fa5a15a88a5 (diff)
downloadgo-tangerine-849408dda60fe32d7abb78d103b09ca0bc7b5a60.tar.gz
go-tangerine-849408dda60fe32d7abb78d103b09ca0bc7b5a60.tar.zst
go-tangerine-849408dda60fe32d7abb78d103b09ca0bc7b5a60.zip
Peer handling
Diffstat (limited to 'peer.go')
-rw-r--r--peer.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/peer.go b/peer.go
new file mode 100644
index 000000000..0c8d38772
--- /dev/null
+++ b/peer.go
@@ -0,0 +1,93 @@
+package main
+
+import (
+ "net"
+ "errors"
+ "log"
+)
+
+type InMsg struct {
+ msgType string // Specifies how the encoded data should be interpreted
+ data []byte // RLP encoded data
+}
+
+func ReadMessage(conn net.Conn) (*InMsg, error) {
+ buff := make([]byte, 4069)
+
+ // Wait for a message from this peer
+ n, err := conn.Read(buff)
+ if err != nil {
+ return nil, err
+ } else if n == 0 {
+ return nil, errors.New("Empty message received")
+ }
+
+ // Read the header (MAX n)
+ decoder := NewRlpDecoder(buff[:n])
+ t := decoder.Get(0).AsString()
+ if t == "" {
+ return nil, errors.New("Data contained no data type")
+ }
+
+ return &InMsg{msgType: t, data: decoder.Get(1).AsBytes()}, nil
+}
+
+type OutMsg struct {
+ data []byte
+}
+
+type Peer struct {
+ server *Server
+ conn net.Conn
+ outputQueue chan OutMsg
+ quit chan bool
+}
+
+func NewPeer(conn net.Conn, server *Server) *Peer {
+ return &Peer{
+ outputQueue: make(chan OutMsg, 1), // Buffered chan of 1 is enough
+ quit: make(chan bool),
+
+ server: server,
+ conn: conn,
+ }
+}
+
+// Outputs any RLP encoded data to the peer
+func (p *Peer) QueueMessage(data []byte) {
+ p.outputQueue <- OutMsg{data: data}
+}
+
+func (p *Peer) HandleOutbound() {
+out:
+ for {
+ switch {
+ case <- p.quit:
+ break out
+ }
+ }
+}
+
+func (p *Peer) HandleInbound() {
+ defer p.conn.Close()
+
+out:
+ for {
+ msg, err := ReadMessage(p.conn)
+ if err != nil {
+ log.Println(err)
+
+ break out
+ }
+
+ log.Println(msg)
+ }
+
+ // Notify the out handler we're quiting
+ p.quit <- true
+}
+
+func (p *Peer) Start() {
+ go p.HandleOutbound()
+ go p.HandleInbound()
+}