fix(yamux): doesn't work in a Relayv2 connection (#979)
Co-authored-by: Ludovic Chenut <ludovic@status.im>
This commit is contained in:
parent
39586605d9
commit
7ce2afba13
|
@ -186,6 +186,7 @@ proc remoteClosed(channel: YamuxChannel) {.async.} =
|
||||||
method closeImpl*(channel: YamuxChannel) {.async, gcsafe.} =
|
method closeImpl*(channel: YamuxChannel) {.async, gcsafe.} =
|
||||||
if not channel.closedLocally:
|
if not channel.closedLocally:
|
||||||
channel.closedLocally = true
|
channel.closedLocally = true
|
||||||
|
channel.isEof = true
|
||||||
|
|
||||||
if channel.isReset == false and channel.sendQueue.len == 0:
|
if channel.isReset == false and channel.sendQueue.len == 0:
|
||||||
await channel.conn.write(YamuxHeader.data(channel.id, 0, {Fin}))
|
await channel.conn.write(YamuxHeader.data(channel.id, 0, {Fin}))
|
||||||
|
@ -249,6 +250,7 @@ method readOnce*(
|
||||||
await channel.closedRemotely or channel.receivedData.wait()
|
await channel.closedRemotely or channel.receivedData.wait()
|
||||||
if channel.closedRemotely.done() and channel.recvQueue.len == 0:
|
if channel.closedRemotely.done() and channel.recvQueue.len == 0:
|
||||||
channel.returnedEof = true
|
channel.returnedEof = true
|
||||||
|
channel.isEof = true
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
let toRead = min(channel.recvQueue.len, nbytes)
|
let toRead = min(channel.recvQueue.len, nbytes)
|
||||||
|
@ -454,6 +456,7 @@ method handle*(m: Yamux) {.async, gcsafe.} =
|
||||||
if header.streamId in m.flushed:
|
if header.streamId in m.flushed:
|
||||||
m.flushed.del(header.streamId)
|
m.flushed.del(header.streamId)
|
||||||
if header.streamId mod 2 == m.currentId mod 2:
|
if header.streamId mod 2 == m.currentId mod 2:
|
||||||
|
debug "Peer used our reserved stream id, skipping", id=header.streamId, currentId=m.currentId, peerId=m.connection.peerId
|
||||||
raise newException(YamuxError, "Peer used our reserved stream id")
|
raise newException(YamuxError, "Peer used our reserved stream id")
|
||||||
let newStream = m.createStream(header.streamId, false)
|
let newStream = m.createStream(header.streamId, false)
|
||||||
if m.channels.len >= m.maxChannCount:
|
if m.channels.len >= m.maxChannCount:
|
||||||
|
|
|
@ -47,6 +47,7 @@ proc new*(
|
||||||
limitDuration: uint32,
|
limitDuration: uint32,
|
||||||
limitData: uint64): T =
|
limitData: uint64): T =
|
||||||
let rc = T(conn: conn, limitDuration: limitDuration, limitData: limitData)
|
let rc = T(conn: conn, limitDuration: limitDuration, limitData: limitData)
|
||||||
|
rc.dir = conn.dir
|
||||||
rc.initStream()
|
rc.initStream()
|
||||||
if limitDuration > 0:
|
if limitDuration > 0:
|
||||||
proc checkDurationConnection() {.async.} =
|
proc checkDurationConnection() {.async.} =
|
||||||
|
|
|
@ -19,14 +19,22 @@ import ./helpers
|
||||||
import std/times
|
import std/times
|
||||||
import stew/byteutils
|
import stew/byteutils
|
||||||
|
|
||||||
proc createSwitch(r: Relay): Switch =
|
proc createSwitch(r: Relay = nil, useYamux: bool = false): Switch =
|
||||||
result = SwitchBuilder.new()
|
var builder = SwitchBuilder.new()
|
||||||
.withRng(newRng())
|
.withRng(newRng())
|
||||||
.withAddresses(@[ MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet() ])
|
.withAddresses(@[ MultiAddress.init("/ip4/0.0.0.0/tcp/0").tryGet() ])
|
||||||
.withTcpTransport()
|
.withTcpTransport()
|
||||||
.withMplex()
|
|
||||||
|
if useYamux:
|
||||||
|
builder = builder.withYamux()
|
||||||
|
else:
|
||||||
|
builder = builder.withMplex()
|
||||||
|
|
||||||
|
if r != nil:
|
||||||
|
builder = builder.withCircuitRelay(r)
|
||||||
|
|
||||||
|
return builder
|
||||||
.withNoise()
|
.withNoise()
|
||||||
.withCircuitRelay(r)
|
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
suite "Circuit Relay V2":
|
suite "Circuit Relay V2":
|
||||||
|
@ -122,7 +130,8 @@ suite "Circuit Relay V2":
|
||||||
expect(ReservationError):
|
expect(ReservationError):
|
||||||
discard await cl1.reserve(src2.peerInfo.peerId, addrs)
|
discard await cl1.reserve(src2.peerInfo.peerId, addrs)
|
||||||
|
|
||||||
suite "Connection":
|
for (useYamux, muxName) in [(false, "Mplex"), (true, "Yamux")]:
|
||||||
|
suite "Circuit Relay V2 Connection using " & muxName:
|
||||||
asyncTeardown:
|
asyncTeardown:
|
||||||
checkTrackers()
|
checkTrackers()
|
||||||
var
|
var
|
||||||
|
@ -149,9 +158,9 @@ suite "Circuit Relay V2":
|
||||||
ldata = 16384
|
ldata = 16384
|
||||||
srcCl = RelayClient.new()
|
srcCl = RelayClient.new()
|
||||||
dstCl = RelayClient.new()
|
dstCl = RelayClient.new()
|
||||||
src = createSwitch(srcCl)
|
src = createSwitch(srcCl, useYamux)
|
||||||
dst = createSwitch(dstCl)
|
dst = createSwitch(dstCl, useYamux)
|
||||||
rel = newStandardSwitch()
|
rel = createSwitch(nil, useYamux)
|
||||||
|
|
||||||
asyncTest "Connection succeed":
|
asyncTest "Connection succeed":
|
||||||
proto.handler = proc(conn: Connection, proto: string) {.async.} =
|
proto.handler = proc(conn: Connection, proto: string) {.async.} =
|
||||||
|
@ -230,20 +239,20 @@ suite "Circuit Relay V2":
|
||||||
await conn.writeLp("do you expect a lorem ipsum or...?")
|
await conn.writeLp("do you expect a lorem ipsum or...?")
|
||||||
check "surprise me!" == string.fromBytes(await conn.readLp(1024))
|
check "surprise me!" == string.fromBytes(await conn.readLp(1024))
|
||||||
await conn.writeLp("""Call me Ishmael. Some years ago--never mind how long
|
await conn.writeLp("""Call me Ishmael. Some years ago--never mind how long
|
||||||
precisely--having little or no money in my purse, and nothing
|
precisely--having little or no money in my purse, and nothing
|
||||||
particular to interest me on shore, I thought I would sail about a
|
particular to interest me on shore, I thought I would sail about a
|
||||||
little and see the watery part of the world. It is a way I have of
|
little and see the watery part of the world. It is a way I have of
|
||||||
driving off the spleen and regulating the circulation. Whenever I
|
driving off the spleen and regulating the circulation. Whenever I
|
||||||
find myself growing grim about the mouth; whenever it is a damp,
|
find myself growing grim about the mouth; whenever it is a damp,
|
||||||
drizzly November in my soul; whenever I find myself involuntarily
|
drizzly November in my soul; whenever I find myself involuntarily
|
||||||
pausing before coffin warehouses, and bringing up the rear of every
|
pausing before coffin warehouses, and bringing up the rear of every
|
||||||
funeral I meet; and especially whenever my hypos get such an upper
|
funeral I meet; and especially whenever my hypos get such an upper
|
||||||
hand of me, that it requires a strong moral principle to prevent me
|
hand of me, that it requires a strong moral principle to prevent me
|
||||||
from deliberately stepping into the street, and methodically knocking
|
from deliberately stepping into the street, and methodically knocking
|
||||||
people's hats off--then, I account it high time to get to sea as soon
|
people's hats off--then, I account it high time to get to sea as soon
|
||||||
as I can. This is my substitute for pistol and ball. With a
|
as I can. This is my substitute for pistol and ball. With a
|
||||||
philosophical flourish Cato throws himself upon his sword; I quietly
|
philosophical flourish Cato throws himself upon his sword; I quietly
|
||||||
take to the ship.""")
|
take to the ship.""")
|
||||||
rv2 = Relay.new(reservationTTL=initDuration(seconds=ttl),
|
rv2 = Relay.new(reservationTTL=initDuration(seconds=ttl),
|
||||||
limitDuration=ldur,
|
limitDuration=ldur,
|
||||||
limitData=ldata)
|
limitData=ldata)
|
||||||
|
@ -322,7 +331,7 @@ take to the ship.""")
|
||||||
raise newException(CatchableError, "Should not be here")
|
raise newException(CatchableError, "Should not be here")
|
||||||
let
|
let
|
||||||
rel2Cl = RelayClient.new(canHop = true)
|
rel2Cl = RelayClient.new(canHop = true)
|
||||||
rel2 = createSwitch(rel2Cl)
|
rel2 = createSwitch(rel2Cl, useYamux)
|
||||||
rv2 = Relay.new()
|
rv2 = Relay.new()
|
||||||
rv2.setup(rel)
|
rv2.setup(rel)
|
||||||
rel.mount(rv2)
|
rel.mount(rv2)
|
||||||
|
@ -347,6 +356,7 @@ take to the ship.""")
|
||||||
|
|
||||||
expect(DialFailedError):
|
expect(DialFailedError):
|
||||||
conn = await src.dial(dst.peerInfo.peerId, addrs, customProtoCodec)
|
conn = await src.dial(dst.peerInfo.peerId, addrs, customProtoCodec)
|
||||||
|
if not conn.isNil():
|
||||||
await allFutures(conn.close())
|
await allFutures(conn.close())
|
||||||
await allFutures(src.stop(), dst.stop(), rel.stop(), rel2.stop())
|
await allFutures(src.stop(), dst.stop(), rel.stop(), rel2.stop())
|
||||||
|
|
||||||
|
@ -381,9 +391,9 @@ take to the ship.""")
|
||||||
clientA = RelayClient.new(canHop = true)
|
clientA = RelayClient.new(canHop = true)
|
||||||
clientB = RelayClient.new(canHop = true)
|
clientB = RelayClient.new(canHop = true)
|
||||||
clientC = RelayClient.new(canHop = true)
|
clientC = RelayClient.new(canHop = true)
|
||||||
switchA = createSwitch(clientA)
|
switchA = createSwitch(clientA, useYamux)
|
||||||
switchB = createSwitch(clientB)
|
switchB = createSwitch(clientB, useYamux)
|
||||||
switchC = createSwitch(clientC)
|
switchC = createSwitch(clientC, useYamux)
|
||||||
|
|
||||||
switchA.mount(protoBCA)
|
switchA.mount(protoBCA)
|
||||||
switchB.mount(protoCAB)
|
switchB.mount(protoCAB)
|
||||||
|
|
Loading…
Reference in New Issue