-
Notifications
You must be signed in to change notification settings - Fork 69
improvement(yamux): make the window size configurable #987
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
4a8446f
e318308
63c0c08
6ba7613
3fb5827
c247b37
1013cc2
bbed0b4
87032bf
a05854f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,7 @@ logScope: | |
| const | ||
| YamuxCodec* = "/yamux/1.0.0" | ||
| YamuxVersion = 0.uint8 | ||
| DefaultWindowSize = 256000 | ||
| DefaultWindowSize* = 256000 | ||
| MaxChannelCount = 200 | ||
|
|
||
| when defined(libp2p_yamux_metrics): | ||
|
|
@@ -351,7 +351,13 @@ proc open*(channel: YamuxChannel) {.async, gcsafe.} = | |
| trace "Try to open channel twice" | ||
| return | ||
| channel.opened = true | ||
| await channel.conn.write(YamuxHeader.data(channel.id, 0, {if channel.isSrc: Syn else: Ack})) | ||
| let delta = | ||
| if channel.maxRecvWindow < DefaultWindowSize: 0'u32 | ||
| else: channel.maxRecvWindow.uint32 - DefaultWindowSize | ||
| await channel.conn.write(YamuxHeader.windowUpdate( | ||
| channel.id, | ||
| delta, | ||
| {if channel.isSrc: Syn else: Ack})) | ||
|
|
||
| method getWrapped*(channel: YamuxChannel): Connection = channel.conn | ||
|
|
||
|
|
@@ -362,6 +368,7 @@ type | |
| currentId: uint32 | ||
| isClosed: bool | ||
| maxChannCount: int | ||
| windowSize: int | ||
|
|
||
| proc lenBySrc(m: Yamux, isSrc: bool): int = | ||
| for v in m.channels.values(): | ||
|
|
@@ -375,11 +382,11 @@ proc cleanupChann(m: Yamux, channel: YamuxChannel) {.async.} = | |
| if channel.isReset and channel.recvWindow > 0: | ||
| m.flushed[channel.id] = channel.recvWindow | ||
|
|
||
| proc createStream(m: Yamux, id: uint32, isSrc: bool): YamuxChannel = | ||
| proc createStream(m: Yamux, id: uint32, isSrc: bool, recvWindow: int): YamuxChannel = | ||
| result = YamuxChannel( | ||
| id: id, | ||
| maxRecvWindow: DefaultWindowSize, | ||
| recvWindow: DefaultWindowSize, | ||
| maxRecvWindow: recvWindow, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why can
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because maxRecvWindow could be, for example, 64k but the peer you're connected to will always assume your recvWindow is 256k (or larger if you enlarge it during the SYN/ACK). In this case, the recvWindow will be larger than maxRecvWindow until it receives 192k. Then it'll not update to something larger than 64k.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The spec does not really exclude the case that the desired That being said, we should either
I'd prefer 2), but I do not have a strong opinion here. @diegomrsantos @lchenut wdyt?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My interpretation is that other peers will always assume your initial |
||
| recvWindow: if recvWindow > DefaultWindowSize: recvWindow else: DefaultWindowSize, | ||
| sendWindow: DefaultWindowSize, | ||
| isSrc: isSrc, | ||
| conn: m.connection, | ||
|
|
@@ -455,7 +462,7 @@ method handle*(m: Yamux) {.async, gcsafe.} = | |
| m.flushed.del(header.streamId) | ||
| if header.streamId mod 2 == m.currentId mod 2: | ||
| raise newException(YamuxError, "Peer used our reserved stream id") | ||
| let newStream = m.createStream(header.streamId, false) | ||
| let newStream = m.createStream(header.streamId, false, m.windowSize) | ||
| if m.channels.len >= m.maxChannCount: | ||
| await newStream.reset() | ||
| continue | ||
|
|
@@ -515,15 +522,18 @@ method newStream*( | |
|
|
||
| if m.channels.len > m.maxChannCount - 1: | ||
| raise newException(TooManyChannels, "max allowed channel count exceeded") | ||
| let stream = m.createStream(m.currentId, true) | ||
| let stream = m.createStream(m.currentId, true, m.windowSize) | ||
| m.currentId += 2 | ||
| if not lazy: | ||
| await stream.open() | ||
| return stream | ||
|
|
||
| proc new*(T: type[Yamux], conn: Connection, maxChannCount: int = MaxChannelCount): T = | ||
| proc new*(T: type[Yamux], conn: Connection, | ||
| maxChannCount: int = MaxChannelCount, | ||
| windowSize: int = DefaultWindowSize): T = | ||
| T( | ||
| connection: conn, | ||
| currentId: if conn.dir == Out: 1 else: 2, | ||
| maxChannCount: maxChannCount | ||
| maxChannCount: maxChannCount, | ||
| windowSize: windowSize | ||
lchenut marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ) | ||
Uh oh!
There was an error while loading. Please reload this page.