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
9fd76e33
Unverified
Commit
9fd76e33
authored
Feb 17, 2018
by
Péter Szilágyi
Committed by
GitHub
Feb 17, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #16109 from karalabe/p2p-bond-check
p2p/discover: validate bond against lastpong, not db presence
parents
4e61ed02
aeedec40
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
26 additions
and
25 deletions
+26
-25
database.go
p2p/discover/database.go
+11
-6
database_test.go
p2p/discover/database_test.go
+9
-9
table.go
p2p/discover/table.go
+3
-3
udp.go
p2p/discover/udp.go
+1
-1
udp_test.go
p2p/discover/udp_test.go
+2
-6
No files found.
p2p/discover/database.go
View file @
9fd76e33
...
...
@@ -257,7 +257,7 @@ func (db *nodeDB) expireNodes() error {
}
// Skip the node if not expired yet (and not self)
if
!
bytes
.
Equal
(
id
[
:
],
db
.
self
[
:
])
{
if
seen
:=
db
.
lastPong
(
id
);
seen
.
After
(
threshold
)
{
if
seen
:=
db
.
bondTime
(
id
);
seen
.
After
(
threshold
)
{
continue
}
}
...
...
@@ -278,13 +278,18 @@ func (db *nodeDB) updateLastPing(id NodeID, instance time.Time) error {
return
db
.
storeInt64
(
makeKey
(
id
,
nodeDBDiscoverPing
),
instance
.
Unix
())
}
//
lastPong retrieves the time of the last successful contact
from remote node.
func
(
db
*
nodeDB
)
lastPong
(
id
NodeID
)
time
.
Time
{
//
bondTime retrieves the time of the last successful pong
from remote node.
func
(
db
*
nodeDB
)
bondTime
(
id
NodeID
)
time
.
Time
{
return
time
.
Unix
(
db
.
fetchInt64
(
makeKey
(
id
,
nodeDBDiscoverPong
)),
0
)
}
// updateLastPong updates the last time a remote node successfully contacted.
func
(
db
*
nodeDB
)
updateLastPong
(
id
NodeID
,
instance
time
.
Time
)
error
{
// hasBond reports whether the given node is considered bonded.
func
(
db
*
nodeDB
)
hasBond
(
id
NodeID
)
bool
{
return
time
.
Since
(
db
.
bondTime
(
id
))
<
nodeDBNodeExpiration
}
// updateBondTime updates the last pong time of a node.
func
(
db
*
nodeDB
)
updateBondTime
(
id
NodeID
,
instance
time
.
Time
)
error
{
return
db
.
storeInt64
(
makeKey
(
id
,
nodeDBDiscoverPong
),
instance
.
Unix
())
}
...
...
@@ -327,7 +332,7 @@ seek:
if
n
.
ID
==
db
.
self
{
continue
seek
}
if
now
.
Sub
(
db
.
lastPong
(
n
.
ID
))
>
maxAge
{
if
now
.
Sub
(
db
.
bondTime
(
n
.
ID
))
>
maxAge
{
continue
seek
}
for
i
:=
range
nodes
{
...
...
p2p/discover/database_test.go
View file @
9fd76e33
...
...
@@ -125,13 +125,13 @@ func TestNodeDBFetchStore(t *testing.T) {
t
.
Errorf
(
"ping: value mismatch: have %v, want %v"
,
stored
,
inst
)
}
// Check fetch/store operations on a node pong object
if
stored
:=
db
.
lastPong
(
node
.
ID
);
stored
.
Unix
()
!=
0
{
if
stored
:=
db
.
bondTime
(
node
.
ID
);
stored
.
Unix
()
!=
0
{
t
.
Errorf
(
"pong: non-existing object: %v"
,
stored
)
}
if
err
:=
db
.
update
LastPong
(
node
.
ID
,
inst
);
err
!=
nil
{
if
err
:=
db
.
update
BondTime
(
node
.
ID
,
inst
);
err
!=
nil
{
t
.
Errorf
(
"pong: failed to update: %v"
,
err
)
}
if
stored
:=
db
.
lastPong
(
node
.
ID
);
stored
.
Unix
()
!=
inst
.
Unix
()
{
if
stored
:=
db
.
bondTime
(
node
.
ID
);
stored
.
Unix
()
!=
inst
.
Unix
()
{
t
.
Errorf
(
"pong: value mismatch: have %v, want %v"
,
stored
,
inst
)
}
// Check fetch/store operations on a node findnode-failure object
...
...
@@ -224,8 +224,8 @@ func TestNodeDBSeedQuery(t *testing.T) {
if
err
:=
db
.
updateNode
(
seed
.
node
);
err
!=
nil
{
t
.
Fatalf
(
"node %d: failed to insert: %v"
,
i
,
err
)
}
if
err
:=
db
.
update
LastPong
(
seed
.
node
.
ID
,
seed
.
pong
);
err
!=
nil
{
t
.
Fatalf
(
"node %d: failed to insert
lastPong
: %v"
,
i
,
err
)
if
err
:=
db
.
update
BondTime
(
seed
.
node
.
ID
,
seed
.
pong
);
err
!=
nil
{
t
.
Fatalf
(
"node %d: failed to insert
bondTime
: %v"
,
i
,
err
)
}
}
...
...
@@ -332,8 +332,8 @@ func TestNodeDBExpiration(t *testing.T) {
if
err
:=
db
.
updateNode
(
seed
.
node
);
err
!=
nil
{
t
.
Fatalf
(
"node %d: failed to insert: %v"
,
i
,
err
)
}
if
err
:=
db
.
update
LastPong
(
seed
.
node
.
ID
,
seed
.
pong
);
err
!=
nil
{
t
.
Fatalf
(
"node %d: failed to update
pong
: %v"
,
i
,
err
)
if
err
:=
db
.
update
BondTime
(
seed
.
node
.
ID
,
seed
.
pong
);
err
!=
nil
{
t
.
Fatalf
(
"node %d: failed to update
bondTime
: %v"
,
i
,
err
)
}
}
// Expire some of them, and check the rest
...
...
@@ -365,8 +365,8 @@ func TestNodeDBSelfExpiration(t *testing.T) {
if
err
:=
db
.
updateNode
(
seed
.
node
);
err
!=
nil
{
t
.
Fatalf
(
"node %d: failed to insert: %v"
,
i
,
err
)
}
if
err
:=
db
.
update
LastPong
(
seed
.
node
.
ID
,
seed
.
pong
);
err
!=
nil
{
t
.
Fatalf
(
"node %d: failed to update
pong
: %v"
,
i
,
err
)
if
err
:=
db
.
update
BondTime
(
seed
.
node
.
ID
,
seed
.
pong
);
err
!=
nil
{
t
.
Fatalf
(
"node %d: failed to update
bondTime
: %v"
,
i
,
err
)
}
}
// Expire the nodes and make sure self has been evacuated too
...
...
p2p/discover/table.go
View file @
9fd76e33
...
...
@@ -455,7 +455,7 @@ func (tab *Table) loadSeedNodes(bond bool) {
}
for
i
:=
range
seeds
{
seed
:=
seeds
[
i
]
age
:=
log
.
Lazy
{
Fn
:
func
()
interface
{}
{
return
time
.
Since
(
tab
.
db
.
lastPong
(
seed
.
ID
))
}}
age
:=
log
.
Lazy
{
Fn
:
func
()
interface
{}
{
return
time
.
Since
(
tab
.
db
.
bondTime
(
seed
.
ID
))
}}
log
.
Debug
(
"Found seed node in database"
,
"id"
,
seed
.
ID
,
"addr"
,
seed
.
addr
(),
"age"
,
age
)
tab
.
add
(
seed
)
}
...
...
@@ -596,7 +596,7 @@ func (tab *Table) bond(pinged bool, id NodeID, addr *net.UDPAddr, tcpPort uint16
}
// Start bonding if we haven't seen this node for a while or if it failed findnode too often.
node
,
fails
:=
tab
.
db
.
node
(
id
),
tab
.
db
.
findFails
(
id
)
age
:=
time
.
Since
(
tab
.
db
.
lastPong
(
id
))
age
:=
time
.
Since
(
tab
.
db
.
bondTime
(
id
))
var
result
error
if
fails
>
0
||
age
>
nodeDBNodeExpiration
{
log
.
Trace
(
"Starting bonding ping/pong"
,
"id"
,
id
,
"known"
,
node
!=
nil
,
"failcount"
,
fails
,
"age"
,
age
)
...
...
@@ -663,7 +663,7 @@ func (tab *Table) ping(id NodeID, addr *net.UDPAddr) error {
if
err
:=
tab
.
net
.
ping
(
id
,
addr
);
err
!=
nil
{
return
err
}
tab
.
db
.
update
LastPong
(
id
,
time
.
Now
())
tab
.
db
.
update
BondTime
(
id
,
time
.
Now
())
return
nil
}
...
...
p2p/discover/udp.go
View file @
9fd76e33
...
...
@@ -613,7 +613,7 @@ func (req *findnode) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte
if
expired
(
req
.
Expiration
)
{
return
errExpired
}
if
t
.
db
.
node
(
fromID
)
==
nil
{
if
!
t
.
db
.
hasBond
(
fromID
)
{
// No bond exists, we don't process the packet. This prevents
// an attack vector where the discovery protocol could be used
// to amplify traffic in a DDOS attack. A malicious actor
...
...
p2p/discover/udp_test.go
View file @
9fd76e33
...
...
@@ -247,12 +247,8 @@ func TestUDP_findnode(t *testing.T) {
// ensure there's a bond with the test node,
// findnode won't be accepted otherwise.
test
.
table
.
db
.
updateNode
(
NewNode
(
PubkeyID
(
&
test
.
remotekey
.
PublicKey
),
test
.
remoteaddr
.
IP
,
uint16
(
test
.
remoteaddr
.
Port
),
99
,
))
test
.
table
.
db
.
updateBondTime
(
PubkeyID
(
&
test
.
remotekey
.
PublicKey
),
time
.
Now
())
// check that closest neighbors are returned.
test
.
packetIn
(
nil
,
findnodePacket
,
&
findnode
{
Target
:
testTarget
,
Expiration
:
futureExp
})
expected
:=
test
.
table
.
closest
(
targetHash
,
bucketSize
)
...
...
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