Fake UDP packet source address on localhost only - javascript

I am working on a way to force the game Alien vs. Predator 2 to connect to specific IP address. The reason is, that quite often the server is reachable, but the UDP broadcast the game sends to discover it do not reach the server.
On localhost, this kind of discovery always works. So what I thought I could do is a simple console application that will listen on UDP broadcast from the game and reply. The reply needs to look like it came from the real server's IP, not localhost.
I figure that with no ISP/firewalls involved, this should be much simpler.
I read Node.JS UDP dgrams documentation. It says how to specify target address and port for a message, but it seems to rely on OS' behavior for filling up the source IP and port.
Is there another way?

You can try adding a line to your operating system host file:
127.0.0.1 **the_original_game_server_ip**
This will redirect all traffic to localhost instead of the game server.
Now just create a console application that listens to the game server port.

Related

Can Chrome or Firefox open a network port and serve connections using javascript?

For a mostly offline browser game I'm researching the possibility to run a WebRTC signalling server from a browser.
I can imagine that security-wise it's a big no-no to open a port and serve connections from a browser (or service worker), but I cannot* find any information on this.
Q. Can Chrome, Firefox (or perhaps any other major browser) open a network port and serve connections using javascript? Or is this fundamentally disallowed by browser design?
*) For sake of completeness, I did find one option (maybe), but it's overly complex, and therefore isn't very appealing. There is a javascript package called filerjs, which allows for a posix-like filesytem in the browser, I think using indexedb, that would allow for a nodejs installation in the browser. I did not further investigate it, so no idea if it actually works, and if a connection could be served this way.
I don't think that you can run a signaling server in the browser. But you say "mostly offline", does that mean that the peers are connected to the internet, but playing from the same LAN? Or are they completely offline? Here are a few ideas:
Signaling server on the web
Even if the signaling server is running on the web, chances are that WebRTC will connect directly through the LAN (to be tested, and it may depend on how the browser selects the ICE candidates).
Manual signaling
Now, the signaling server is only there to exchange SDP messages. So you could theoretically copy-paste the offer and answer (or copy it manually, or scan it with a QR code). It may not be practical, but for instance you could try hardcoding the SDP offer/answer. The two players would need to exchange information somehow, though:
The ICE candidates (those are IPs) that you would need to create the SDP message
The SDP type (one has to be the offer, the other has to be the answer)
I never tried it, but maybe your UI could tell the player "Please share the following IPs to the other player, and enter their IPs below. Also select if you are the offerer or the answerer". But you see that it seems a bit convoluted...
Signaling server in the LAN
If the peers are completely offline and the manual signaling is too convoluted, my next idea would be to run the signaling server in the LAN, and have the peers connect to it. You could even make it such that your game first tries to contact your signaling server on the Internet, and if it fails (because it is offline), it could fallback and try to contact the one in the LAN (maybe it would need to ask the user for the IP of the signaling server, then).

WebRTC fails to connect P2P even though peers can send UDP packets to each other

I was under the impression that WebRTC goes to great lengths to achieve P2P connectivity despite NATs. [1][2] That's why I was surprised to learn that WebRTC fails to connect peers in some situations where a P2P connection is easy to achieve. I would like to understand why this happens, and if there is anything I can do to improve the situation.
Why do I claim that P2P is easy to achieve in some of these situations? I claim this because I have set up an experiment with 2 devices on different networks:
Device F is connected to the internet behind Full-cone NAT
Device S is connected to the internet behind Symmetric NAT
I can easily achieve a P2P connection between these devices in the following manner:
Device F binds a connection to a random (unpredictable) port and sends a UDP packet through that port to anywhere on the internet. Because F is behind Full-cone NAT, this packet has "hole-punched" the port open, allowing any external addresses to now send packets through that port. In my case the port that I opened locally appears to be the same as the external port. (If the external port was different from the local port, we could use something like STUN to figure out the external port.)
Device S binds a connection to a random (unpredictable) port and sends a UDP packet through that port to the external IP and port of Device F. This packet can be delivered, because the port was hole-punched open in step 1. After this packet, Device S has hole-punched through its own port, allowing packets from Device F to be sent back through it. Device F will know where to send the packets, because the packet that S sent contains the external IP and port. Because Device S has Symmetric NAT, the hole-punching didn't open the port for all traffic, only for traffic from Device F (the external IP and port of Device F).
I used Python to verify that I am able to open a P2P connection between these devices and send messages in both directions, as described above. I don't understand why WebRTC is unable to achieve a P2P connection like this.
Why do I claim that WebRTC fails to connect in some of these situations where a connection should be easy? I claim this because I tried to achieve a WebRTC P2P connection with 3 different code examples. All of the examples worked when devices were in the same local network, but didn't work when the devices were in different networks (the setup described above). None of the libraries I tried provided any useful debugging information to figure out what went wrong, and chrome://webrtc-internals didn't provide any useful information either. I also tried in Firefox to verify that this issue is not implementation-specific.
To be specific, I tried the following code examples:
simple-peer, a WebRTC library. I tried the first example code in the README.
PeerJS, another WebRTC library. I tried the demo page they have set up.
A code snippet from a Stackoverflow answer. [3]
In all 3 experiments I also tried to switch which device initiates the connection and which device receives it.
Since this issue isn't specific to WebRTC implementation, and it isn't specific to any particular WebRTC JavaScript library, I'm beginning to suspect that the spec for WebRTC is broken in some fundamental way, preventing WebRTC from achieving P2P connections in situations where they would be easy to achieve. Am I missing something here?
[1] https://webrtc.org/getting-started/turn-server states: "For most WebRTC applications to function a server is required for relaying the traffic between peers, since a direct socket is often not possible between the clients". This gives the impression that WebRTC should be able to achieve a P2P connection in a scenario where it is easy to achieve.
[2] https://webrtcforthecurious.com/docs/03-connecting/ states: "WebRTC will gather all the information it can and will go to great lengths to achieve bi-directional communication between two WebRTC Agents." This also gives the impression that WebRTC should be able to achieve a P2P connection in a scenario where it is easy to achieve.
[3] WebRTC datachannel with manual signaling, example please?

How to encrypt socket.io client using CLI (instead of through browser)?

This is less of a "what is wrong with my code" and more of a "is this possible or even required". I've been working on this CLI chat using socket.io and socket.io, and then I thought "what if this was a production server exposed to the internet - does this need security?"
I've seen a lot of stuff online about using nginx or express (or both) to achieve this - but no mention of any type of encryption if you were trying to do this via CLI (eg, "node file.js" for this to emit traffic to the webserver but securely). I've tried a few examples (as they were provided) and then adapted my existing code to incorporate the same config, but now I'm starting to think that perhaps it isn't possible because they are already secure? (In my understanding the server listening port is just for the server to bind client to another port to send data)
I can't seem to find a cut and dry answer (past forum posts seem to contradict each other on this) from what I've found.
I tried running my server and connecting up via 2 clients (one localhost on the same as the server and one on another IP on my LAN) and ran wireshark to see if I could see my other host (which I couldn't) but I could see unencrypted traffic being sent... So while this isn't broadcast traffic to all, how easy would this be to snoop on if you knew the exact port server & client were using to communicate?
Hope someone can help explain these nuances
The long answer is complex. The short one is:
Anything you send through a Wire is easy to spoof. This is why TCP over TLS exists. Any communication through a TLS secured channel would assure your data between client & server will be secret (as long as you trust the server you are good-to-go).
Socket.io uses WebSocket under the hood, (same as there is HTTPS for HTTP over TLS) there is WSS for WS over TLS. So if you set up your server to accept WSS (maybe only WSS to be sure there is no unencrypted connection going on) and you make sure to connect the client to a wss://.... endpoint, you have achieved client-server security. It's that simple.
If you can not trust the server, and what you are doing is essentially a message broker, you can go further and experiment with end-to-end encryption (https://en.wikipedia.org/wiki/End-to-end_encryption).

Webrtc Getting blocked by Firewall (iceConnection:Failed)

I have simple web app,
Client1 logs in and socket connections is made to signal.php
Client2 logs in and socket connections is made to signal.php again
Client2 sends offer to client1 via signal.php
client1 sends answe to client2
ice candidiates are exchanged
So this works fine when the remote system's windows firewall is Off but when the firewall is On the ice connection fails after ice candidates are gathered.
I am using xirsys Turn/Stun servers. I have tried to find a way to find a way to make sure my app runs even if firewall is On. I have seen other webrtc example which do no get blocked by firewall. What am I missing here ?????
UPDATE
Did some more testing with following results
Does not matter if Firewall is On or Off on the client making connection. If the Firwall is On who is getting the Offer the connections fails
Example: Consider client 1 is making the offer and client 2 is receiving the offer. If client 2 has firwall On, the connection fails. If firewall is Off the connection is etablished. Does not matter if client 1 has its firewall On or Off. If client 1 and 2 or on same computer, the connections is always sucessful.
You need to compare the types of TURN servers used by your app which does not work with the ones that work. chrome://webrtc-internals shows the servers.
do you use TURN/TCP and TURN/TLS?
on which ports do the the TURN servers run?
for the working service, what kind of connection is used (see here for how to determine this)
And there are cases where the connection will fail. Your UX needs to deal with those too.

Locate server on LAN in JavaScript

TL;DR
In Javascript, how do you to find the IP of all servers running a specified program on a specified port in the LAN?
Background
I'm writing a server in node.js that is supposed to connect users browsers as controllers to a common device on which a game is running. The browsers are running a web app based on html and Javascript. The connection is based on socket.io.
I'd like for the web app to be able to find all available instances of this server in the LAN in order to create a server list for the user to choose from.
Is there a way to make the server discoverable by the web app on the local network in Javascript, and in that case: how?
Ideas
Have the server broadcast its IP to all devices on the LAN and have the web app listen for these messages (No idea how to do this without node on the client)
Connect to every IP on the network and see if the connection is successful. (Does not seem feasible)
Scan every IP on the network and connect only to those where the port is open. (Once again, no idea how to do this without node on the client and does not seeem feasible either.)
EDIT
The server is supposed to be portable and work independently, without any central system backing it up or providing matchmaking for clients. It is a LAN only server and should work even without internet access.
There is no way for you do this. Sorry. Since there is no exposure to UDP on client-side JavaScript, broadcasting is out of question. Any attempt on massive scanning will quickly raise flags on network monitoring software. You have to use a known address.

Categories

Resources