neo-go/pkg/network/tcp.go

106 lines
2.1 KiB
Go
Raw Normal View History

2018-01-26 18:04:13 +00:00
package network
import (
2018-01-31 19:11:08 +00:00
"bytes"
2018-01-26 18:04:13 +00:00
"net"
2018-01-31 19:11:08 +00:00
"github.com/anthdm/neo-go/pkg/network/payload"
2018-01-26 18:04:13 +00:00
)
func listenTCP(s *Server, port string) error {
ln, err := net.Listen("tcp", port)
if err != nil {
return err
}
s.listener = ln
2018-01-26 18:04:13 +00:00
for {
conn, err := ln.Accept()
if err != nil {
return err
}
2018-01-29 18:17:49 +00:00
go handleConnection(s, conn)
2018-01-26 18:04:13 +00:00
}
}
2018-01-28 13:59:32 +00:00
func connectToRemoteNode(s *Server, address string) {
conn, err := net.Dial("tcp", address)
if err != nil {
2018-01-28 17:42:22 +00:00
s.logger.Printf("failed to connect to remote node %s", address)
2018-01-28 13:59:32 +00:00
if conn != nil {
conn.Close()
}
return
}
2018-01-29 18:17:49 +00:00
go handleConnection(s, conn)
2018-01-28 13:59:32 +00:00
}
2018-01-26 18:04:13 +00:00
func connectToSeeds(s *Server, addrs []string) {
for _, addr := range addrs {
2018-01-28 13:59:32 +00:00
go connectToRemoteNode(s, addr)
2018-01-26 18:04:13 +00:00
}
}
2018-01-29 18:17:49 +00:00
func handleConnection(s *Server, conn net.Conn) {
2018-01-31 19:11:08 +00:00
peer := NewTCPPeer(conn, s)
2018-01-26 18:04:13 +00:00
s.register <- peer
// remove the peer from connected peers and cleanup the connection.
defer func() {
2018-01-28 17:42:22 +00:00
// all cleanup will happen in the server's loop when unregister is received.
2018-01-26 18:04:13 +00:00
s.unregister <- peer
}()
// Start a goroutine that will handle all writes to the registered peer.
go peer.writeLoop()
2018-01-31 19:11:08 +00:00
// Read from the connection and decode it into a Message ready for processing.
buf := make([]byte, 1024)
2018-01-26 18:04:13 +00:00
for {
2018-01-31 19:11:08 +00:00
_, err := conn.Read(buf)
if err != nil {
s.logger.Printf("conn read error: %s", err)
break
}
2018-01-28 10:20:42 +00:00
msg := &Message{}
2018-01-31 19:11:08 +00:00
if err := msg.decode(bytes.NewReader(buf)); err != nil {
s.logger.Printf("decode error %s", err)
2018-01-26 18:04:13 +00:00
break
}
2018-01-31 19:11:08 +00:00
handleMessage(msg, s, peer)
}
}
func handleMessage(msg *Message, s *Server, p *TCPPeer) {
command := msg.commandType()
s.logger.Printf("%d :: IN :: %s :: %v", p.id(), command, msg)
switch command {
case cmdVersion:
resp := s.handleVersionCmd(msg, p)
p.isVerack = true
p.nonce = msg.Payload.(*payload.Version).Nonce
p.send <- resp
case cmdAddr:
s.handleAddrCmd(msg, p)
case cmdGetAddr:
s.handleGetaddrCmd(msg, p)
case cmdInv:
resp := s.handleInvCmd(msg, p)
p.send <- resp
case cmdBlock:
case cmdConsensus:
case cmdTX:
case cmdVerack:
go s.sendLoop(p)
case cmdGetHeaders:
case cmdGetBlocks:
case cmdGetData:
case cmdHeaders:
default:
2018-01-26 18:04:13 +00:00
}
}