neoneo-go/pkg/network/tcp.go
2018-01-31 20:11:08 +01:00

105 lines
2.1 KiB
Go

package network
import (
"bytes"
"net"
"github.com/anthdm/neo-go/pkg/network/payload"
)
func listenTCP(s *Server, port string) error {
ln, err := net.Listen("tcp", port)
if err != nil {
return err
}
s.listener = ln
for {
conn, err := ln.Accept()
if err != nil {
return err
}
go handleConnection(s, conn)
}
}
func connectToRemoteNode(s *Server, address string) {
conn, err := net.Dial("tcp", address)
if err != nil {
s.logger.Printf("failed to connect to remote node %s", address)
if conn != nil {
conn.Close()
}
return
}
go handleConnection(s, conn)
}
func connectToSeeds(s *Server, addrs []string) {
for _, addr := range addrs {
go connectToRemoteNode(s, addr)
}
}
func handleConnection(s *Server, conn net.Conn) {
peer := NewTCPPeer(conn, s)
s.register <- peer
// remove the peer from connected peers and cleanup the connection.
defer func() {
// all cleanup will happen in the server's loop when unregister is received.
s.unregister <- peer
}()
// Start a goroutine that will handle all writes to the registered peer.
go peer.writeLoop()
// Read from the connection and decode it into a Message ready for processing.
buf := make([]byte, 1024)
for {
_, err := conn.Read(buf)
if err != nil {
s.logger.Printf("conn read error: %s", err)
break
}
msg := &Message{}
if err := msg.decode(bytes.NewReader(buf)); err != nil {
s.logger.Printf("decode error %s", err)
break
}
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:
}
}