-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Is it possible to network v86 instances together inside the browser? #1094
Comments
Yes, see https://github.com/copy/v86/blob/master/examples/two_instances.html (haven't tested it in a while, but it should still be working) |
I've been playing around with the new fetch based network driver and have to say, its really friendly to begin work on (I even made my own handler for TCP in a day that uses https://github.com/MercuryWorkshop/wsproxy and is much faster than the relay based networking available), you could probably play around with that + webrtc if you're looking for cross computer communication. alternatively you could hook virtio console and serial and send messages that way, it would be a form of networking, just not through the NIC |
Is it possible to have multiple interfaces? I am looking to have a mini web based network. For now I am looking into possibly writing a switch program that matches Mac addresses. |
I think the switch is the best idea here, there doesn't seem to be a way to create multiple NICs in v86 in starter.js, you'd probably need to do substantial modifications |
I might just use premade simulators. This is starting to seem way more ambitious than I realized. Thanks |
I'd accept a PR to support multiple adapters in the constructor. We'll soon have three network backends (wsproxy, fetch and wisp) and two adapters (ne2k and virtio-net), and it would be nice to support arbitrary combinations too. |
If you need to connect instances within in a browser frame without server side, you can try to use Broadcast Channel API to receive/send Ethernet frames. Here I'm tried to make simple example: <!doctype html>
<script src="libv86.js"></script>
<script>
"use strict";
// from src/browser/fetch_network.js
function a2ethaddr(bytes) {
return [0,1,2,3,4,5].map((i) => bytes[i].toString(16)).map(x => x.length === 1 ? "0" + x : x).join(":");
};
window.onload = function()
{
var emulator = window.emulator = new V86({
...
});
emulator.add_listener("net0-mac", function(mac) {
emulator.mac = mac;
document.title = "mesh: " + emulator.mac;
});
// [connecting to a channel (or creating a new one)]
var broadcast = new BroadcastChannel("v86-mesh");
// [receiving]
broadcast.addEventListener("message", function(e) {
const packet = e.data;
const eth = {
dest: a2ethaddr(packet.subarray(0, 6)),
src: a2ethaddr(packet.subarray(6, 12))
};
// don't accept packets not addressed to us
// ff:ff:ff:ff:ff:ff - broadcast
if((eth.dest === emulator.mac) || (eth.dest === "ff:ff:ff:ff:ff:ff")) {
console.log("packet from %s to %s", eth.src, eth.dest);
emulator.bus.send("net0-receive", packet);
};
});
// [sending]
emulator.add_listener("net0-send", function(packet) {
broadcast.postMessage(packet);
});
}
</script>
<div id="screen_container">
<div style="white-space: pre; font: 14px monospace; line-height: 14px"></div>
<canvas style="display: none"></canvas>
</div> Partly based on examples/two_instances.html and you also need to set a static IP for each VM, Currently it uses one network adapter, but could probably be redesigned for multiple network adapters. |
Well that is not an approach that I had considered. It would be closer to a hub instead of switch and I would need to come up with some sort of lock to prevent two instances broadcasting at the same time but it might be feasible. Thanks |
I have a working proof of concept. Thanks @SuperMaxusa |
https://darin755.codeberg.page/netemu/src/ to run commands on the web worker you can run |
@SuperMaxusa That is pretty cool, could you send a PR to add as an example? Just a comment, I believe the following check is not necessary (it's already done in the network card) // don't accept packets not addressed to us
// ff:ff:ff:ff:ff:ff - broadcast
if((eth.dest === emulator.mac) || (eth.dest === "ff:ff:ff:ff:ff:ff")) { |
Indeed, thanks for your comment! Seems that I left this for clear logging on each VM. |
I am looking for a way to network multiple instances together without having to do anything server side. This will be a part of a virtual networking lab for educational purposes. It might be possible to use serial to setup an connection but it would be tricky and not ideal. Ideally it would be nice to have a local network interface that can be used to make a virtual switch in the browser. You could have some sort of hook that runs a handler program when a frame is received. From there I could write a proper switch that could do routing based on mac.
The text was updated successfully, but these errors were encountered: