go-ethereum/p2p/adapters/rlpx.go
nolash 9822d7405e p2p/simulations: improvement and adding msg events
* Conceals rw in messenger type
* Adds generic remote control for nodes in network sim
* Adds msg type and event to sim, journal
* Msg http output, http options handler
* Msg event added to "cytoscape" for output to visualizer
* Msg event structure changed to fit "cytodata" logic
* Fix for handling CORS/PUT requests:
* fallthrough OPTIONS method handler
* Access-Control-Allow-Methods header added (note that the servermux panics if sent empty method value through http)
2017-05-06 14:23:38 +01:00

126 lines
3.3 KiB
Go

// Copyright 2016 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package adapters
import (
"fmt"
"net"
//"encoding/binary"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover"
)
// devp2p RLPx underlay support
type RLPx struct {
id *NodeId
net *p2p.Server
addr []byte
m func(p2p.MsgReadWriter) Messenger
r Reporter
}
type RLPxMessenger struct {
rw p2p.MsgReadWriter
}
func NewRLPxMessenger(rw p2p.MsgReadWriter) Messenger {
return Messenger(&RLPxMessenger{rw: rw})
}
func NewRLPx(addr []byte, srv *p2p.Server, m func(p2p.MsgReadWriter) Messenger) *RLPx {
return &RLPx{
net: srv,
addr: addr,
m: m,
}
}
func NewReportingRLPx(addr []byte, srv *p2p.Server, m func(p2p.MsgReadWriter) Messenger, r Reporter) *RLPx {
rlpx := NewRLPx(addr, srv, m)
rlpx.r = r
srv.PeerConnHook = func(p *p2p.Peer) {
r.DidConnect(rlpx.id, &NodeId{p.ID()})
}
srv.PeerDisconnHook = func(p *p2p.Peer) {
r.DidDisconnect(rlpx.id, &NodeId{p.ID()})
}
return rlpx
}
func (self *RLPxMessenger) SendMsg(code uint64, msg interface{}) error {
return p2p.Send(self.rw, code, msg)
}
func (self *RLPxMessenger) ReadMsg() (p2p.Msg, error) {
return self.rw.ReadMsg()
}
func (self *RLPxMessenger) Close() {
}
func (self *RLPx) LocalAddr() []byte {
return self.addr
}
func (self *RLPx) Connect(enode []byte) error {
// TCP/UDP node address encoded with enode url scheme
// <node-id>@<ip-address>:<tcp-port>(?udp=<udp-port>)
node, err := discover.ParseNode(string(enode))
if err != nil {
return fmt.Errorf("invalid node URL: %v", err)
}
self.net.AddPeer(node)
return nil
}
func (self *RLPx) Messenger(rw p2p.MsgReadWriter) Messenger {
return self.m(rw)
}
//func (self *RLPx) Disconnect(p *p2p.Peer, rw p2p.MsgReadWriter) error {
func (self *RLPx) Disconnect(b []byte) error {
//p.Disconnect(p2p.DiscSubprotocolError)
//d, _ := binary.Uvarint(b)
//p.Disconnect(p2p.DiscReason(d))
return nil
}
// ParseAddr take two arguments, advertised in handshake and the one set on the peer struct
// and constructs the remote address object
func (self *RLPx) ParseAddr(s []byte, remoteAddr string) ([]byte, error) {
// returns self advertised node connection info (listening address w enodes)
// IP will get repaired on the other end if missing
// or resolved via ID by discovery at dialout
n, err := discover.ParseNode(string(s))
if err != nil {
return nil, err
}
// repair reported address if IP missing
if n.IP.IsUnspecified() {
host, _, err := net.SplitHostPort(remoteAddr)
if err != nil {
return nil, err
}
n.IP = net.ParseIP(host)
}
return []byte(n.String()), nil
}