This commit is contained in:
anthdm 2018-01-27 08:37:07 +01:00
parent 98a6831d6a
commit d76b86febd
2 changed files with 33 additions and 13 deletions

View file

@ -98,6 +98,8 @@ func (m *Message) commandType() commandType {
return cmdVersion return cmdVersion
case "verack": case "verack":
return cmdVerack return cmdVerack
case "getaddr":
return cmdGetAddr
case "addr": case "addr":
return cmdAddr return cmdAddr
case "getheaders": case "getheaders":
@ -211,7 +213,7 @@ func newVersionPayload(p uint16, ua string, h uint32, r bool) *Version {
Services: 1, Services: 1,
Timestamp: 12345, Timestamp: 12345,
Port: p, Port: p,
Nonce: 1911099534, Nonce: 19110,
UserAgent: []byte(ua), UserAgent: []byte(ua),
StartHeight: 0, StartHeight: 0,
Relay: r, Relay: r,

View file

@ -68,7 +68,9 @@ func NewServer(net NetMode) *Server {
} }
s := &Server{ s := &Server{
userAgent: fmt.Sprintf("/NEO:%s/", version), // It is important to have this user agent correct. Otherwise we will get
// disconnected.
userAgent: fmt.Sprintf("\v/NEO:%s/", version),
logger: logger, logger: logger,
peers: make(map[*Peer]bool), peers: make(map[*Peer]bool),
register: make(chan *Peer), register: make(chan *Peer),
@ -118,6 +120,12 @@ func (s *Server) shutdown() {
} }
} }
func (s *Server) disconnect(p *Peer) {
p.conn.Close()
close(p.send)
s.unregister <- p
}
func (s *Server) loop() { func (s *Server) loop() {
for { for {
select { select {
@ -133,7 +141,10 @@ func (s *Server) loop() {
peer.send <- resp peer.send <- resp
} }
case peer := <-s.unregister: case peer := <-s.unregister:
s.logger.Printf("peer %s disconnected", peer.conn.RemoteAddr()) if _, ok := s.peers[peer]; ok {
delete(s.peers, peer)
s.logger.Printf("peer %s disconnected", peer.conn.RemoteAddr())
}
case tuple := <-s.message: case tuple := <-s.message:
if err := s.processMessage(tuple.msg, tuple.peer); err != nil { if err := s.processMessage(tuple.msg, tuple.peer); err != nil {
s.logger.Fatalf("failed to process message: %s", err) s.logger.Fatalf("failed to process message: %s", err)
@ -147,16 +158,15 @@ func (s *Server) loop() {
// TODO: unregister peers on error. // TODO: unregister peers on error.
// processMessage processes the received message from a remote node. // processMessage processes the received message from a remote node.
func (s *Server) processMessage(msg *Message, peer *Peer) error { func (s *Server) processMessage(msg *Message, peer *Peer) error {
rpcLogger.Printf("IN :: %+v", msg) rpcLogger.Printf("IN :: %+v", string(msg.Command))
switch msg.commandType() { switch msg.commandType() {
case cmdVersion: case cmdVersion:
v, _ := msg.decodePayload() v, err := msg.decodePayload()
resp, err := s.handleVersionCmd(v.(*Version))
if err != nil { if err != nil {
return err return err
} }
peer.send <- resp s.handleVersionCmd(v.(*Version), peer)
case cmdVerack: case cmdVerack:
case cmdGetAddr: case cmdGetAddr:
case cmdAddr: case cmdAddr:
@ -187,14 +197,22 @@ func (s *Server) handlePeerConnected() (*Message, error) {
return msg, nil return msg, nil
} }
// Version declares the server's version when a new connection is been made. // Version declares the server's version.
// We respond with a instant "verack" message. func (s *Server) handleVersionCmd(v *Version, peer *Peer) {
func (s *Server) handleVersionCmd(v *Version) (*Message, error) {
// TODO: check version and verify to trust that node. // TODO: check version and verify to trust that node.
// Empty payload for the verack message. payload := newVersionPayload(s.port, s.userAgent, 0, s.relay)
msg := newMessage(s.net, cmdVerack, nil) b, err := payload.encode()
return msg, nil if err != nil {
s.disconnect(peer)
return
}
versionMsg := newMessage(s.net, cmdVersion, b)
peer.send <- versionMsg
peer.verack = true
verackMsg := newMessage(s.net, cmdVerack, nil)
peer.send <- verackMsg
} }
func logo() string { func logo() string {