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
a0191910
Commit
a0191910
authored
Jun 28, 2015
by
Felix Lange
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1341 from karalabe/proto-version-negotiation
p2p: support protocol version negotiation
parents
b9ebdffd
216fc267
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
110 additions
and
6 deletions
+110
-6
peer.go
p2p/peer.go
+9
-2
peer_test.go
p2p/peer_test.go
+95
-0
protocol.go
p2p/protocol.go
+6
-4
No files found.
p2p/peer.go
View file @
a0191910
...
...
@@ -249,15 +249,22 @@ func countMatchingProtocols(protocols []Protocol, caps []Cap) int {
// matchProtocols creates structures for matching named subprotocols.
func
matchProtocols
(
protocols
[]
Protocol
,
caps
[]
Cap
,
rw
MsgReadWriter
)
map
[
string
]
*
protoRW
{
sort
.
Sort
(
capsByName
(
caps
))
sort
.
Sort
(
capsByName
AndVersion
(
caps
))
offset
:=
baseProtocolLength
result
:=
make
(
map
[
string
]
*
protoRW
)
outer
:
for
_
,
cap
:=
range
caps
{
for
_
,
proto
:=
range
protocols
{
if
proto
.
Name
==
cap
.
Name
&&
proto
.
Version
==
cap
.
Version
&&
result
[
cap
.
Name
]
==
nil
{
if
proto
.
Name
==
cap
.
Name
&&
proto
.
Version
==
cap
.
Version
{
// If an old protocol version matched, revert it
if
old
:=
result
[
cap
.
Name
];
old
!=
nil
{
offset
-=
old
.
Length
}
// Assign the new match
result
[
cap
.
Name
]
=
&
protoRW
{
Protocol
:
proto
,
offset
:
offset
,
in
:
make
(
chan
Msg
),
w
:
rw
}
offset
+=
proto
.
Length
continue
outer
}
}
...
...
p2p/peer_test.go
View file @
a0191910
...
...
@@ -196,3 +196,98 @@ func TestNewPeer(t *testing.T) {
p
.
Disconnect
(
DiscAlreadyConnected
)
// Should not hang
}
func
TestMatchProtocols
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
Remote
[]
Cap
Local
[]
Protocol
Match
map
[
string
]
protoRW
}{
{
// No remote capabilities
Local
:
[]
Protocol
{{
Name
:
"a"
}},
},
{
// No local protocols
Remote
:
[]
Cap
{{
Name
:
"a"
}},
},
{
// No mutual protocols
Remote
:
[]
Cap
{{
Name
:
"a"
}},
Local
:
[]
Protocol
{{
Name
:
"b"
}},
},
{
// Some matches, some differences
Remote
:
[]
Cap
{{
Name
:
"local"
},
{
Name
:
"match1"
},
{
Name
:
"match2"
}},
Local
:
[]
Protocol
{{
Name
:
"match1"
},
{
Name
:
"match2"
},
{
Name
:
"remote"
}},
Match
:
map
[
string
]
protoRW
{
"match1"
:
{
Protocol
:
Protocol
{
Name
:
"match1"
}},
"match2"
:
{
Protocol
:
Protocol
{
Name
:
"match2"
}}},
},
{
// Various alphabetical ordering
Remote
:
[]
Cap
{{
Name
:
"aa"
},
{
Name
:
"ab"
},
{
Name
:
"bb"
},
{
Name
:
"ba"
}},
Local
:
[]
Protocol
{{
Name
:
"ba"
},
{
Name
:
"bb"
},
{
Name
:
"ab"
},
{
Name
:
"aa"
}},
Match
:
map
[
string
]
protoRW
{
"aa"
:
{
Protocol
:
Protocol
{
Name
:
"aa"
}},
"ab"
:
{
Protocol
:
Protocol
{
Name
:
"ab"
}},
"ba"
:
{
Protocol
:
Protocol
{
Name
:
"ba"
}},
"bb"
:
{
Protocol
:
Protocol
{
Name
:
"bb"
}}},
},
{
// No mutual versions
Remote
:
[]
Cap
{{
Version
:
1
}},
Local
:
[]
Protocol
{{
Version
:
2
}},
},
{
// Multiple versions, single common
Remote
:
[]
Cap
{{
Version
:
1
},
{
Version
:
2
}},
Local
:
[]
Protocol
{{
Version
:
2
},
{
Version
:
3
}},
Match
:
map
[
string
]
protoRW
{
""
:
{
Protocol
:
Protocol
{
Version
:
2
}}},
},
{
// Multiple versions, multiple common
Remote
:
[]
Cap
{{
Version
:
1
},
{
Version
:
2
},
{
Version
:
3
},
{
Version
:
4
}},
Local
:
[]
Protocol
{{
Version
:
2
},
{
Version
:
3
}},
Match
:
map
[
string
]
protoRW
{
""
:
{
Protocol
:
Protocol
{
Version
:
3
}}},
},
{
// Various version orderings
Remote
:
[]
Cap
{{
Version
:
4
},
{
Version
:
1
},
{
Version
:
3
},
{
Version
:
2
}},
Local
:
[]
Protocol
{{
Version
:
2
},
{
Version
:
3
},
{
Version
:
1
}},
Match
:
map
[
string
]
protoRW
{
""
:
{
Protocol
:
Protocol
{
Version
:
3
}}},
},
{
// Versions overriding sub-protocol lengths
Remote
:
[]
Cap
{{
Version
:
1
},
{
Version
:
2
},
{
Version
:
3
},
{
Name
:
"a"
}},
Local
:
[]
Protocol
{{
Version
:
1
,
Length
:
1
},
{
Version
:
2
,
Length
:
2
},
{
Version
:
3
,
Length
:
3
},
{
Name
:
"a"
}},
Match
:
map
[
string
]
protoRW
{
""
:
{
Protocol
:
Protocol
{
Version
:
3
}},
"a"
:
{
Protocol
:
Protocol
{
Name
:
"a"
},
offset
:
3
}},
},
}
for
i
,
tt
:=
range
tests
{
result
:=
matchProtocols
(
tt
.
Local
,
tt
.
Remote
,
nil
)
if
len
(
result
)
!=
len
(
tt
.
Match
)
{
t
.
Errorf
(
"test %d: negotiation mismatch: have %v, want %v"
,
i
,
len
(
result
),
len
(
tt
.
Match
))
continue
}
// Make sure all negotiated protocols are needed and correct
for
name
,
proto
:=
range
result
{
match
,
ok
:=
tt
.
Match
[
name
]
if
!
ok
{
t
.
Errorf
(
"test %d, proto '%s': negotiated but shouldn't have"
,
i
,
name
)
continue
}
if
proto
.
Name
!=
match
.
Name
{
t
.
Errorf
(
"test %d, proto '%s': name mismatch: have %v, want %v"
,
i
,
name
,
proto
.
Name
,
match
.
Name
)
}
if
proto
.
Version
!=
match
.
Version
{
t
.
Errorf
(
"test %d, proto '%s': version mismatch: have %v, want %v"
,
i
,
name
,
proto
.
Version
,
match
.
Version
)
}
if
proto
.
offset
-
baseProtocolLength
!=
match
.
offset
{
t
.
Errorf
(
"test %d, proto '%s': offset mismatch: have %v, want %v"
,
i
,
name
,
proto
.
offset
-
baseProtocolLength
,
match
.
offset
)
}
}
// Make sure no protocols missed negotiation
for
name
,
_
:=
range
tt
.
Match
{
if
_
,
ok
:=
result
[
name
];
!
ok
{
t
.
Errorf
(
"test %d, proto '%s': not negotiated, should have"
,
i
,
name
)
continue
}
}
}
}
p2p/protocol.go
View file @
a0191910
...
...
@@ -43,8 +43,10 @@ func (cap Cap) String() string {
return
fmt
.
Sprintf
(
"%s/%d"
,
cap
.
Name
,
cap
.
Version
)
}
type
capsByName
[]
Cap
type
capsByName
AndVersion
[]
Cap
func
(
cs
capsByName
)
Len
()
int
{
return
len
(
cs
)
}
func
(
cs
capsByName
)
Less
(
i
,
j
int
)
bool
{
return
cs
[
i
]
.
Name
<
cs
[
j
]
.
Name
}
func
(
cs
capsByName
)
Swap
(
i
,
j
int
)
{
cs
[
i
],
cs
[
j
]
=
cs
[
j
],
cs
[
i
]
}
func
(
cs
capsByNameAndVersion
)
Len
()
int
{
return
len
(
cs
)
}
func
(
cs
capsByNameAndVersion
)
Swap
(
i
,
j
int
)
{
cs
[
i
],
cs
[
j
]
=
cs
[
j
],
cs
[
i
]
}
func
(
cs
capsByNameAndVersion
)
Less
(
i
,
j
int
)
bool
{
return
cs
[
i
]
.
Name
<
cs
[
j
]
.
Name
||
(
cs
[
i
]
.
Name
==
cs
[
j
]
.
Name
&&
cs
[
i
]
.
Version
<
cs
[
j
]
.
Version
)
}
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