Skip to content

Commit

Permalink
added TCPConnection.on_shutdown() and TCPConnection.on_close()
Browse files Browse the repository at this point in the history
- both methods must be overloaded by the network adapter, just like TCPConnection.on_data()
- on_shutdown() informs the network adapter that the client has closed its half of the connection (FIN)
- on_close() informs the network adapter that the client has fully closed the connection (RST)
- added call to on_shutdown() when we receive a TCP packet with active FIN flag from guest
- added call to on_close() when we receive a TCP packet with active RST flag from guest
- added calls to on_close() when we have to tear down the connection in fake_network.js
- added implementation of on_shutdown() and on_close() in wisp_network.js

The default implementation of these methods is to do nothing.

These methods do not apply to fetch-based networking, fetch() only supports HTTP and it doesn't matter if the client closes its end of the connection after it has sent its HTTP request. Hence FetchNetworkAdapter does not override these methods.

Note that WISP currently only supports close(), as a workaround shutdown() is implemented like close() which might be incorrect (missing support for half-closed TCP connections).
  • Loading branch information
chschnell authored and copy committed Nov 26, 2024
1 parent 5a3b77d commit f820081
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
13 changes: 12 additions & 1 deletion src/browser/fake_network.js
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,7 @@ TCPConnection.prototype.process = function(packet) {
}
else if(packet.tcp.rst) {
// dbg_log(`TCP[${this.tuple}]: received RST in state "${this.state}"`, LOG_FETCH);
this.on_close();
this.release();
return;
}
Expand Down Expand Up @@ -1116,6 +1117,7 @@ TCPConnection.prototype.process = function(packet) {
dbg_log(`TCP[${this.tuple}]: ERROR: ack underflow (pkt=${packet.tcp.ackn} last=${this.last_received_ackn}), resetting`, LOG_FETCH);
const reply = this.packet_reply(packet, {rst: true});
this.net.receive(make_packet(this.net.eth_encoder_buf, reply));
this.on_close();
this.release();
return;
}
Expand All @@ -1131,7 +1133,7 @@ TCPConnection.prototype.process = function(packet) {
// dbg_log(`TCP[${this.tuple}]: received FIN in state "${this.state}, next "${TCP_STATE_CLOSE_WAIT}""`, LOG_FETCH);
reply.tcp.ack = true;
this.state = TCP_STATE_CLOSE_WAIT;
// NOTE that we should forward the CLOSE event from the guest here, but neither WISP nor fetch() support that
this.on_shutdown();
}
else if(this.state === TCP_STATE_FIN_WAIT_1) {
if(packet.tcp.ack) {
Expand All @@ -1152,6 +1154,7 @@ TCPConnection.prototype.process = function(packet) {
else {
// dbg_log(`TCP[${this.tuple}]: ERROR: received FIN in unexpected TCP state "${this.state}", resetting`, LOG_FETCH);
this.release();
this.on_close();
reply.tcp.rst = true;
}
this.net.receive(make_packet(this.net.eth_encoder_buf, reply));
Expand Down Expand Up @@ -1237,6 +1240,14 @@ TCPConnection.prototype.close = function() {
this.pump();
};

TCPConnection.prototype.on_shutdown = function() {
// forward FIN event from guest to network provider
};

TCPConnection.prototype.on_close = function() {
// forward RST event from guest to network provider
};

TCPConnection.prototype.release = function() {
if(this.net.tcp_conn[this.tuple]) {
// dbg_log(`TCP[${this.tuple}]: connection closed in state "${this.state}"`, LOG_FETCH);
Expand Down
32 changes: 25 additions & 7 deletions src/browser/wisp_network.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,16 @@ WispNetworkAdapter.prototype.register_ws = function(wisp_url) {
};

WispNetworkAdapter.prototype.send_packet = function(data, type, stream_id) {
if(this.connections[stream_id].congestion > 0) {
if(type === "DATA") {
this.connections[stream_id].congestion--;
if(this.connections[stream_id]) {
if(this.connections[stream_id].congestion > 0) {
if(type === "DATA") {
this.connections[stream_id].congestion--;
}
this.wispws.send(data);
} else {
this.connections[stream_id].congested = true;
this.congested_buffer.push({data: data, type: type});
}
this.wispws.send(data);
} else {
this.connections[stream_id].congested = true;
this.congested_buffer.push({data: data, type: type});
}
};

Expand Down Expand Up @@ -219,6 +221,22 @@ WispNetworkAdapter.prototype.send = function(data)
}
};

tcp_conn.on_shutdown = () => {
this.send_wisp_frame({
type: "CLOSE",
stream_id: tcp_conn.stream_id,
reason: 0x02 // 0x02: Voluntary stream closure
});
};

tcp_conn.on_close = () => {
this.send_wisp_frame({
type: "CLOSE",
stream_id: tcp_conn.stream_id,
reason: 0x02 // 0x02: Voluntary stream closure
});
};

this.send_wisp_frame({
type: "CONNECT",
stream_id: tcp_conn.stream_id,
Expand Down

0 comments on commit f820081

Please sign in to comment.