Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
4accc187
Commit
4accc187
authored
May 04, 2015
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
eth, p2p: add trusted node list beside static list
parent
2382da41
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
59 additions
and
51 deletions
+59
-51
backend.go
eth/backend.go
+12
-12
handshake.go
p2p/handshake.go
+7
-7
handshake_test.go
p2p/handshake_test.go
+2
-2
server.go
p2p/server.go
+21
-11
server_test.go
p2p/server_test.go
+17
-19
No files found.
eth/backend.go
View file @
4accc187
...
...
@@ -41,8 +41,8 @@ var (
discover
.
MustParseNode
(
"enode://487611428e6c99a11a9795a6abe7b529e81315ca6aad66e2a2fc76e3adf263faba0d35466c2f8f68d561dbefa8878d4df5f1f2ddb1fbeab7f42ffb8cd328bd4a@5.1.83.226:30303"
),
}
// Path within <datadir> to search for the static node list
staticNodes
=
"static-nodes.json"
staticNodes
=
"static-nodes.json"
// Path within <datadir> to search for the static node list
trustedNodes
=
"trusted-nodes.json"
// Path within <datadir> to search for the trusted node list
)
type
Config
struct
{
...
...
@@ -102,23 +102,22 @@ func (cfg *Config) parseBootNodes() []*discover.Node {
return
ns
}
// parseStaticNodes parses a list of discovery node URLs either given literally,
// or loaded from a .json file.
func
(
cfg
*
Config
)
parseStaticNodes
()
[]
*
discover
.
Node
{
// Short circuit if no static node config is present
path
:=
filepath
.
Join
(
cfg
.
DataDir
,
staticNodes
)
// parseNodes parses a list of discovery node URLs loaded from a .json file.
func
(
cfg
*
Config
)
parseNodes
(
file
string
)
[]
*
discover
.
Node
{
// Short circuit if no node config is present
path
:=
filepath
.
Join
(
cfg
.
DataDir
,
file
)
if
_
,
err
:=
os
.
Stat
(
path
);
err
!=
nil
{
return
nil
}
// Load the
static
nodes from the config file
// Load the nodes from the config file
blob
,
err
:=
ioutil
.
ReadFile
(
path
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Failed to access
static
nodes: %v"
,
err
)
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Failed to access nodes: %v"
,
err
)
return
nil
}
nodelist
:=
[]
string
{}
if
err
:=
json
.
Unmarshal
(
blob
,
&
nodelist
);
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Failed to load
static
nodes: %v"
,
err
)
glog
.
V
(
logger
.
Error
)
.
Infof
(
"Failed to load nodes: %v"
,
err
)
return
nil
}
// Interpret the list as a discovery node array
...
...
@@ -129,7 +128,7 @@ func (cfg *Config) parseStaticNodes() []*discover.Node {
}
node
,
err
:=
discover
.
ParseNode
(
url
)
if
err
!=
nil
{
glog
.
V
(
logger
.
Error
)
.
Infof
(
"
Static n
ode URL %s: %v
\n
"
,
url
,
err
)
glog
.
V
(
logger
.
Error
)
.
Infof
(
"
N
ode URL %s: %v
\n
"
,
url
,
err
)
continue
}
nodes
=
append
(
nodes
,
node
)
...
...
@@ -288,7 +287,8 @@ func New(config *Config) (*Ethereum, error) {
NAT
:
config
.
NAT
,
NoDial
:
!
config
.
Dial
,
BootstrapNodes
:
config
.
parseBootNodes
(),
StaticNodes
:
config
.
parseStaticNodes
(),
StaticNodes
:
config
.
parseNodes
(
staticNodes
),
TrustedNodes
:
config
.
parseNodes
(
trustedNodes
),
NodeDatabase
:
nodeDb
,
}
if
len
(
config
.
Port
)
>
0
{
...
...
p2p/handshake.go
View file @
4accc187
...
...
@@ -70,21 +70,21 @@ type protoHandshake struct {
// If dial is non-nil, the connection the local node is the initiator.
// If atcap is true, the connection will be disconnected with DiscTooManyPeers
// after the key exchange.
func
setupConn
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
dial
*
discover
.
Node
,
atcap
bool
)
(
*
conn
,
error
)
{
func
setupConn
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
dial
*
discover
.
Node
,
atcap
bool
,
trusted
map
[
discover
.
NodeID
]
bool
)
(
*
conn
,
error
)
{
if
dial
==
nil
{
return
setupInboundConn
(
fd
,
prv
,
our
,
atcap
)
return
setupInboundConn
(
fd
,
prv
,
our
,
atcap
,
trusted
)
}
else
{
return
setupOutboundConn
(
fd
,
prv
,
our
,
dial
,
atcap
)
return
setupOutboundConn
(
fd
,
prv
,
our
,
dial
,
atcap
,
trusted
)
}
}
func
setupInboundConn
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
atcap
bool
)
(
*
conn
,
error
)
{
func
setupInboundConn
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
atcap
bool
,
trusted
map
[
discover
.
NodeID
]
bool
)
(
*
conn
,
error
)
{
secrets
,
err
:=
receiverEncHandshake
(
fd
,
prv
,
nil
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"encryption handshake failed: %v"
,
err
)
}
rw
:=
newRlpxFrameRW
(
fd
,
secrets
)
if
atcap
{
if
atcap
&&
!
trusted
[
secrets
.
RemoteID
]
{
SendItems
(
rw
,
discMsg
,
DiscTooManyPeers
)
return
nil
,
errors
.
New
(
"we have too many peers"
)
}
...
...
@@ -99,13 +99,13 @@ func setupInboundConn(fd net.Conn, prv *ecdsa.PrivateKey, our *protoHandshake, a
return
&
conn
{
rw
,
rhs
},
nil
}
func
setupOutboundConn
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
dial
*
discover
.
Node
,
atcap
bool
)
(
*
conn
,
error
)
{
func
setupOutboundConn
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
dial
*
discover
.
Node
,
atcap
bool
,
trusted
map
[
discover
.
NodeID
]
bool
)
(
*
conn
,
error
)
{
secrets
,
err
:=
initiatorEncHandshake
(
fd
,
prv
,
dial
.
ID
,
nil
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"encryption handshake failed: %v"
,
err
)
}
rw
:=
newRlpxFrameRW
(
fd
,
secrets
)
if
atcap
{
if
atcap
&&
!
trusted
[
secrets
.
RemoteID
]
{
SendItems
(
rw
,
discMsg
,
DiscTooManyPeers
)
return
nil
,
errors
.
New
(
"we have too many peers"
)
}
...
...
p2p/handshake_test.go
View file @
4accc187
...
...
@@ -143,7 +143,7 @@ func TestSetupConn(t *testing.T) {
done
:=
make
(
chan
struct
{})
go
func
()
{
defer
close
(
done
)
conn0
,
err
:=
setupConn
(
fd0
,
prv0
,
hs0
,
node1
,
false
)
conn0
,
err
:=
setupConn
(
fd0
,
prv0
,
hs0
,
node1
,
false
,
nil
)
if
err
!=
nil
{
t
.
Errorf
(
"outbound side error: %v"
,
err
)
return
...
...
@@ -156,7 +156,7 @@ func TestSetupConn(t *testing.T) {
}
}()
conn1
,
err
:=
setupConn
(
fd1
,
prv1
,
hs1
,
nil
,
false
)
conn1
,
err
:=
setupConn
(
fd1
,
prv1
,
hs1
,
nil
,
false
,
nil
)
if
err
!=
nil
{
t
.
Fatalf
(
"inbound side error: %v"
,
err
)
}
...
...
p2p/server.go
View file @
4accc187
...
...
@@ -64,6 +64,10 @@ type Server struct {
// maintained and re-connected on disconnects.
StaticNodes
[]
*
discover
.
Node
// Trusted nodes are used as pre-configured connections which are always
// allowed to connect, even above the peer limit.
TrustedNodes
[]
*
discover
.
Node
// NodeDatabase is the path to the database containing the previously seen
// live nodes in the network.
NodeDatabase
string
...
...
@@ -100,12 +104,13 @@ type Server struct {
ourHandshake
*
protoHandshake
lock
sync
.
RWMutex
// protects running, peers and the trust fields
running
bool
peers
map
[
discover
.
NodeID
]
*
Peer
staticNodes
map
[
discover
.
NodeID
]
*
discover
.
Node
// Map of currently maintained static remote nodes
staticDial
chan
*
discover
.
Node
// Dial request channel reserved for the static nodes
staticCycle
time
.
Duration
// Overrides staticPeerCheckInterval, used for testing
lock
sync
.
RWMutex
// protects running, peers and the trust fields
running
bool
peers
map
[
discover
.
NodeID
]
*
Peer
staticNodes
map
[
discover
.
NodeID
]
*
discover
.
Node
// Map of currently maintained static remote nodes
staticDial
chan
*
discover
.
Node
// Dial request channel reserved for the static nodes
staticCycle
time
.
Duration
// Overrides staticPeerCheckInterval, used for testing
trustedNodes
map
[
discover
.
NodeID
]
bool
// Set of currently trusted remote nodes
ntab
*
discover
.
Table
listener
net
.
Listener
...
...
@@ -115,7 +120,7 @@ type Server struct {
peerWG
sync
.
WaitGroup
// active peer goroutines
}
type
setupFunc
func
(
net
.
Conn
,
*
ecdsa
.
PrivateKey
,
*
protoHandshake
,
*
discover
.
Node
,
bool
)
(
*
conn
,
error
)
type
setupFunc
func
(
net
.
Conn
,
*
ecdsa
.
PrivateKey
,
*
protoHandshake
,
*
discover
.
Node
,
bool
,
map
[
discover
.
NodeID
]
bool
)
(
*
conn
,
error
)
type
newPeerHook
func
(
*
Peer
)
// Peers returns all connected peers.
...
...
@@ -207,7 +212,11 @@ func (srv *Server) Start() (err error) {
srv
.
quit
=
make
(
chan
struct
{})
srv
.
peers
=
make
(
map
[
discover
.
NodeID
]
*
Peer
)
// Create the current trust map, and the associated dialing channel
// Create the current trust maps, and the associated dialing channel
srv
.
trustedNodes
=
make
(
map
[
discover
.
NodeID
]
bool
)
for
_
,
node
:=
range
srv
.
TrustedNodes
{
srv
.
trustedNodes
[
node
.
ID
]
=
true
}
srv
.
staticNodes
=
make
(
map
[
discover
.
NodeID
]
*
discover
.
Node
)
for
_
,
node
:=
range
srv
.
StaticNodes
{
srv
.
staticNodes
[
node
.
ID
]
=
node
...
...
@@ -486,7 +495,7 @@ func (srv *Server) startPeer(fd net.Conn, dest *discover.Node) {
}
srv
.
lock
.
RUnlock
()
conn
,
err
:=
srv
.
setupFunc
(
fd
,
srv
.
PrivateKey
,
srv
.
ourHandshake
,
dest
,
atcap
)
conn
,
err
:=
srv
.
setupFunc
(
fd
,
srv
.
PrivateKey
,
srv
.
ourHandshake
,
dest
,
atcap
,
srv
.
trustedNodes
)
if
err
!=
nil
{
fd
.
Close
()
glog
.
V
(
logger
.
Debug
)
.
Infof
(
"Handshake with %v failed: %v"
,
fd
.
RemoteAddr
(),
err
)
...
...
@@ -542,14 +551,15 @@ func (srv *Server) addPeer(id discover.NodeID, p *Peer) (bool, DiscReason) {
// checkPeer verifies whether a peer looks promising and should be allowed/kept
// in the pool, or if it's of no use.
func
(
srv
*
Server
)
checkPeer
(
id
discover
.
NodeID
)
(
bool
,
DiscReason
)
{
// First up, figure out if the peer is static
// First up, figure out if the peer is static
or trusted
_
,
static
:=
srv
.
staticNodes
[
id
]
trusted
:=
srv
.
trustedNodes
[
id
]
// Make sure the peer passes all required checks
switch
{
case
!
srv
.
running
:
return
false
,
DiscQuitting
case
!
static
&&
len
(
srv
.
peers
)
>=
srv
.
MaxPeers
:
case
!
static
&&
!
trusted
&&
len
(
srv
.
peers
)
>=
srv
.
MaxPeers
:
return
false
,
DiscTooManyPeers
case
srv
.
peers
[
id
]
!=
nil
:
return
false
,
DiscAlreadyConnected
...
...
p2p/server_test.go
View file @
4accc187
...
...
@@ -22,7 +22,7 @@ func startTestServer(t *testing.T, pf newPeerHook) *Server {
ListenAddr
:
"127.0.0.1:0"
,
PrivateKey
:
newkey
(),
newPeerHook
:
pf
,
setupFunc
:
func
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
dial
*
discover
.
Node
,
atcap
bool
)
(
*
conn
,
error
)
{
setupFunc
:
func
(
fd
net
.
Conn
,
prv
*
ecdsa
.
PrivateKey
,
our
*
protoHandshake
,
dial
*
discover
.
Node
,
atcap
bool
,
trusted
map
[
discover
.
NodeID
]
bool
)
(
*
conn
,
error
)
{
id
:=
randomID
()
rw
:=
newRlpxFrameRW
(
fd
,
secrets
{
MAC
:
zero16
,
...
...
@@ -200,7 +200,7 @@ func TestServerDisconnectAtCap(t *testing.T) {
// Run the handshakes just like a real peer would.
key
:=
newkey
()
hs
:=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
ID
:
discover
.
PubkeyID
(
&
key
.
PublicKey
)}
_
,
err
=
setupConn
(
conn
,
key
,
hs
,
srv
.
Self
(),
false
)
_
,
err
=
setupConn
(
conn
,
key
,
hs
,
srv
.
Self
(),
false
,
srv
.
trustedNodes
)
if
i
==
nconns
-
1
{
// When handling the last connection, the server should
// disconnect immediately instead of running the protocol
...
...
@@ -250,7 +250,7 @@ func TestServerStaticPeers(t *testing.T) {
// Run the handshakes just like a real peer would, and wait for completion
key
:=
newkey
()
shake
:=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
ID
:
discover
.
PubkeyID
(
&
key
.
PublicKey
)}
if
_
,
err
=
setupConn
(
conn
,
key
,
shake
,
server
.
Self
(),
false
);
err
!=
nil
{
if
_
,
err
=
setupConn
(
conn
,
key
,
shake
,
server
.
Self
(),
false
,
server
.
trustedNodes
);
err
!=
nil
{
t
.
Fatalf
(
"conn %d: unexpected error: %v"
,
i
,
err
)
}
<-
started
...
...
@@ -307,19 +307,24 @@ func TestServerStaticPeers(t *testing.T) {
}
}
/*
// Tests that trusted peers and can connect above max peer caps.
func
TestServerTrustedPeers
(
t
*
testing
.
T
)
{
defer
testlog
(
t
)
.
detach
()
// Create a trusted peer to accept connections from
key
:=
newkey
()
trusted
:=
&
discover
.
Node
{
ID
:
discover
.
PubkeyID
(
&
key
.
PublicKey
),
}
// Create a test server with limited connection slots
started
:=
make
(
chan
*
Peer
)
server
:=
&
Server
{
ListenAddr: "127.0.0.1:0",
PrivateKey: newkey(),
MaxPeers: 3,
NoDial: true,
newPeerHook: func(p *Peer) { started <- p },
ListenAddr
:
"127.0.0.1:0"
,
PrivateKey
:
newkey
(),
MaxPeers
:
3
,
NoDial
:
true
,
TrustedNodes
:
[]
*
discover
.
Node
{
trusted
},
newPeerHook
:
func
(
p
*
Peer
)
{
started
<-
p
},
}
if
err
:=
server
.
Start
();
err
!=
nil
{
t
.
Fatal
(
err
)
...
...
@@ -339,18 +344,12 @@ func TestServerTrustedPeers(t *testing.T) {
// Run the handshakes just like a real peer would, and wait for completion
key
:=
newkey
()
shake
:=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
ID
:
discover
.
PubkeyID
(
&
key
.
PublicKey
)}
if _, err = setupConn(conn, key, shake, server.Self(), false); err != nil {
if
_
,
err
=
setupConn
(
conn
,
key
,
shake
,
server
.
Self
(),
false
,
server
.
trustedNodes
);
err
!=
nil
{
t
.
Fatalf
(
"conn %d: unexpected error: %v"
,
i
,
err
)
}
<-
started
}
// Inject a trusted node and dial that (we'll connect from this end, don't need IP setup)
key := newkey()
trusted := &discover.Node{
ID: discover.PubkeyID(&key.PublicKey),
}
server.AddPeer(trusted)
// Dial from the trusted peer, ensure connection is accepted
conn
,
err
:=
dialer
.
Dial
(
"tcp"
,
server
.
ListenAddr
)
if
err
!=
nil
{
t
.
Fatalf
(
"trusted node: dial error: %v"
,
err
)
...
...
@@ -358,7 +357,7 @@ func TestServerTrustedPeers(t *testing.T) {
defer
conn
.
Close
()
shake
:=
&
protoHandshake
{
Version
:
baseProtocolVersion
,
ID
:
trusted
.
ID
}
if _, err = setupConn(conn, key, shake, server.Self(), false); err != nil {
if
_
,
err
=
setupConn
(
conn
,
key
,
shake
,
server
.
Self
(),
false
,
server
.
trustedNodes
);
err
!=
nil
{
t
.
Fatalf
(
"trusted node: unexpected error: %v"
,
err
)
}
select
{
...
...
@@ -369,7 +368,6 @@ func TestServerTrustedPeers(t *testing.T) {
t
.
Fatalf
(
"trusted node timeout"
)
}
}
*/
func
newkey
()
*
ecdsa
.
PrivateKey
{
key
,
err
:=
crypto
.
GenerateKey
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment