WebRTC on isolated LAN without ice/stun/turn server - webrtc

On an isolated LAN, is there any way that a WebRTC connection can be made simply with the IP addresses assigned by the DHCP server?
I understand that I can accomplish this with Node.js and Socket.io - but I was really hoping to avoid setting up that kind of server with my limited skill set. I'm a science teacher who dabbles in programming, so feel free to keep it simple. Thank you!
UPDATE
Alex, you are correct that I can avoid using a STUN server if all of the computers are on the same local network. Although I had to bite the bullet and install Node.js on my laptop, it was really wasn't complicated. I then tried a whole bunch of 'working examples' that didn't work for me, until I found this one and his GitHub files.
After running the server script in Node, I had a DataChannel connection between two browser windows on the same machine, but not between different computers. I edited the .html files to point to my local server IP address instead of localhost and I could then connect with multiple computers. Then came the real test - could I use this without an internet connection? I found the line that specified using Google's STUN servers and changed it from
var config = {"iceServers":[{"url":"stun:stun.l.google.com:19302"}]};
to just
var config = {"iceServers":[]};
It worked. :-)

Omit the iceServers list:
const pc = new RTCPeerConnection();
Either omit the iceServers list from the RTCPeerConnection constructor, or make it the empty list [].
From RTCPeerConnection docs:
iceServers | optional
An array of RTCIceServer objects, each describing one server which may be used by the ICE agent; these are typically STUN and/or TURN servers. If this isn't specified, the connection attempt will be made with no STUN or TURN server available, which limits the connection to local peers.
webrtc/samples demo
The WebRTC project has a Trickle ICE sample that you can use to see how changes in iceServers effect the candidate address that are gathered. The specific sample you want to look at is.
Run it with defaults set by pressing the Gather candidates button at the bottom of the page. This will return a list of addresses which include the address of the public side of your NAT.
Now remove all the ICE servers from the list and press Gather candidates again, this time you should only see local network addresses.
Notice that, on my network, the 2 public IPv4 addresses (beginning with 98.) only appear when I'm using the default ICE servers. When I use an empty ICE server list, my public IPv4 addresses are no longer discovered. My IPv6 addresses, on the other hand, are the same in both tests because they aren't subject to NAT.
Here is a link to the source code that sets up iceServers and PeerConnection.

Alex, you are correct that I can avoid using a STUN server if all of the computers are on the same local network. Although I had to bite the bullet and install Node.js on my laptop, it was really wasn't complicated. I then tried a whole bunch of 'working examples' that didn't work for me, until I found this one and his GitHub files.
After running the server script in Node, I had a DataChannel connection between two browser windows on the same machine, but not between different computers. I edited the .html files to point to my local server IP address instead of localhost and I could then connect with multiple computers. Then came the real test - could I use this without an internet connection? I found the line that specified using Google's STUN servers and changed it from
var config = {"iceServers":[{"url":"stun:stun.l.google.com:19302"}]};
to just
var config = {"iceServers":[]};

Related

Kurento problems with STUN/TURN servers

So the problem I am having is that the WebSocket connection is working on my KurentoMediaServer, but no data is getting transferred (empty remote URLs). I know that this is because my KurentoMediaServer is running behind a NAT (google compute server), but the STUN/TURN server that I am using does not seem to be working.
This is what my WebRtcEndpoint.conf.ini looks like:
; Only IP address are supported, not domain names for addresses
; You have to find a valid stun server. You can check if it works
; using this tool:
; http://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
stunServerAddress=173.194.66.127
stunServerPort=19302
; turnURL gives the necessary info to configure TURN for WebRTC.
; 'address' must be an IP (not a domain).
; 'transport' is optional (UDP by default).
turnURL=test%40gmail.com:testpassword#66.228.45.110:3478
I have tested this opening all my ports temporarily to see if that was the issue, but it was not. Also test%40gmail.com is my numb TURN registered username and testpassword is my password.
I should also mention that I have my KurentoMediaServer and Application (java server) running behind the same NAT, but I have my webpage running on a separate network. Is there something I need to do with Kurento-Utils.js in order for my webpage to run a separate NAT from my app and kurento media server?
The STUN server you've entered is not working, and the TURN server yields a possible authentication error with those credentials, though it returns some srflx candidates (remember TURN servers are also STUN servers)
When facing an issue like this, the first thing is to check the STUN and TURN servers using this very useful test page.
You should
Look for a valid STUN server
Disable the TURN configuration in you KMS config file, to single out the failure to one server or the other
Make sure everything is working using STUN
Test your TURN server using the test page
Enable TURN and make sure your TURN server is working with Kurento

Mimic client request

I have a server running on my machine. I want to send a request to the server using different IP address to test a web application. I only have the machine on which the server is installed. I have been testing as a single user but now I would like to let the server think that the request is coming from a different ip address even though it is from the same machine. How can I do that?
Here are the 2 solutions that might be possible in your situation
1- To change the ip address :
Pick an ip from the free proxies here: http://www.freeproxylists.net/
And enter the info in firefox just like this page says:
http://www.wikihow.com/Enter-Proxy-Settings-in-Firefox
Note: You may pick a proxy with port 80.
Then you are good to go...
2- Or you might use a Virtual Machine installed on the same computer as the server and access the website right from it but beware not to use bridged connection.

PeerConnection based on local IP's

What I want is, basically, to create a connection between two different computers on same local network. But i want to do this by computers' local IP's. (like 192.168.2.23 etc)
This must be a totally local connection. no TURN or STUN Servers. I am not sure if this is possible. Because there are not much documentation/example/information about WebRTC.
So, how can I create a connection from my computer to another one just passing its local IP as parameter?
Update: To be more clear; imagine there is an html page contains some code that activates my camera and audio services. and another -almost same- page is open in other computer. Waiting a connection request... And there is a textbox in my page to type an IP belongs to other computer on my local network. type 192.168.2.xx and bingo! i have connection between me and other computer.
I want this process as IP based, because there may be more than 2 devices on the network. And all of them are possible devices to create connection. So i need to reach them by their IP's.
Any example code or explanation would be great! even if it tells that this is not possible.
Thanks
Peer discovery is a vital part in any WebRTC application. It's an expensive term for saying: "Hi, I'm computer 4 and I want to talk to you!".
See it as calling a friend over the phone. You need to dial his number first.
This part is not defined in the WebRTC standards. You need to implement this logic in your application. Once you know who you want to call, you need a way of exchanging vital information. This is called signaling, like flo850 put in his answer.
Signaling is needed before any peer-to-peer connection can be set up.
To come up with an idea for your use case of 7 devices in a LAN.
If you have these devices connected to for example a WebSockets server and are in the same channel.
The WebSockets server can be written to route messages to specific receivers.
Devices connected to the channel often are identified with some kind of ID, imagine you use the device's IP.
When you want to talk to computer 4 with IP 192.168.0.4 you send the exchange messages (signaling) on the channel to the receiver with ID, the IP of the device you want to connect with.
How to send the signaling (offer, answer) is described here with example code.
Hope this helps
Users usually sit behind NATs; that's why ICE concept implemented in WebRTC.
If both users are sitting behind same NAT; you can skip ICE servers by passing "NULL" parameter value over "RTCPeerConnection" constructor:
var peer = new [webkit|moz]RTCPeerConnection ( null );
Now, browser will use "host" candidates, also known as "local" candidates.
you still need a signaling server. During the ICE candidate search, your clients will exchange their local ip through this signaling server

GameKit/Peer-to-peer over internet

For an iOS app I am developing, I want multiple phone to connect to each other and be able to voice chat between those devices.
I have it working when both devices are on the same network. This was quite simple and most of the stuff I want to do, is possible.
But now I am adding internet support, which is quite a hassle. I'll first try to explain how I want to match the devices, using a small webservice I set up.
Server
Start a new GameKit session, with session-mode GKSessionModePeer
Find the "Peer ID" of the server on the session I just created
Create a new CFSocketRef on an free port and keep it ready to accept connections
Send Peer ID and Port number to my webservice, running on an external server.
WebService
Webservice receives the information and stores it together with an ID and the IP address of the client in a database.
Send ID back to Server, which displays the ID
Client
When the user chooses to use the "Online" feature of GameKit to search for games, I ask the user for an ID (where the user should input the ID the server receives).
Client connects to the webservice supplying the ID. The webservice returns the information about the session (IP, PORT, Peer ID) of the server.
The user tries to connect to the IP address, with the port information and set up an input and output stream with the server.
This does not work ofcourse, because my network does not allow incoming connections and a random port (from an external network).
But now the question is, how do I solve this? I want to be able to set up a peer to peer connection between 2 devices, those devices could be on the same network, but also on separate networks.
Is there a framework, example or anything showing how to do this? I want to be able to send data from device to device, without sending it to a server first.
I'm not aware of any frameworks that do this. I do however have a lot of experience with p2p networking across multiple networks.
One important rule I learned: when communicating between networks, don't create a direct connection unless necessary. There are just too many factors that can (will?) cause issues, such as firewalls, NATs, etc.
Sure, you can let the connection try first. You can try to connect to the given IP addresses*, but in most cases it will fail. Even when using UPnP and NAT-PMP, you'll find that in a lot of cases (more than half?) you won't be able to accept incoming connections at all.
So make sure to have a backup plan. Make a network layer abstraction that doesn't only listen(), but also connects to a server. That way, when you can't connect to the IPs* of the client, you simply setup a connection via the server and the network abstraction takes care of it all.
Let me reiterate the above: don't rely on incoming connections only, always have a backup plan.
* I write IPs because clients can have multiple local/remote IPs. Always iterate over all these IPs when connecting. Example: my phone has 2 local IPv4 addresses (10.0.0.172 and 10.8.0.2), and an IPv6 address ([2001:x:x::6]). Of these three addresses, only the IPv6 address is publicly reachable, and the two IPv4 addresses are on different subnets so whether you can connect to them depends on the subnet that the other client is on. Always try to connect to both, and fall back to a server-proxied connection when it fails.
** I mentioned IPv6, yes. Let's not forget that IPv6 is not limited by NATs, unlike IPv4, and this means that you're far more likely to get a good connection via IPv6 than IPv4, if supported.

apache on windows network - can't connect to external ip from in network

I created an AMP web application that was originally going to be served from a traditional 3rd party host.
As we finished up, the client decided to host it internally, on a server in their office network. The application is only meant to be available to staff members, but those staff members will often be off-site. I had no involvement in setting up their network, which uses at least one server running windows server 2003. The client machines I saw were XP.
I set up Apache, MySQL and PHP on the server 2003 machine, and installed the application. The application is built on the CodeIgniter framework, so I set the base_url to the internal IP (192.168...), and we tested from within the network. Everything worked fine.
Next, we asked their network guy to open port 80 for apache. I set the base_url to the external IP, and tested from my home (using the external IP as the web address), and it works fine.
However, when attempting to access the application using the external IP from within the network, they're unable to connect. I can reset the base_url to the network IP, and they can access it using the network IP, but then it the application fails when connecting externally (since the base_url, used throughout the application, is pointing to the internal IP).
It suppose I could let CodeIgniter determine the base_url (by leaving the variable as an empty string), but would rather figure out why the external IP fails in-network, and try to correct that.
The server we're using is not dedicated to the AMP stack (in fact, it has at least one other application broadcasting to the internet that must have been using IIS, as well as an FTP server used for office scanners), so I suppose there might be some conflicts there.
I know very little about windows networking. A quick search suggested this might be because of NAT, but didn't offer a work-around.
Their network guy has no suggestions, and said that everything should be fine.
Is it possible to have users inside the network access the Apache server using the external IP, and if so, what needs to happen to enable that?
TYIA
Your client's NAT router is configured to forward packets arriving on its external interface for its external IP with port 80 to the internal machine, port 80, after re-writing the source and destination IP addresses in the packets.
From within the network, attempts to connect to the external IP address will be routed to the default route on the machines, the router's internal interface. This interface is not configured to forward packets back into the network.
Configure the application to listen on all IP addresses. Make sure that the server knows that the clients know it under several hostnames -- the internal IP address and the external IP address.
You might be able to re-write the NAT firewall rules on the router to perform the port forwarding for the internal interface as well, but off-the-shell equipment common in homes and small businesses do not make this task easy. More expensive gear (or home-built *BSD/Linux router machines) can do this without much effort, but it would needlessly add traffic to the router.
This isn't Apache related, nor is it CI related. It's often impossible to reach the external IP address from within the network.
Frankly, I don't know exactly why that is. I do know that it's related to how NAT (Network Address Translation) works or at least how it's implemented.
For a detailed overview of why this is, you should ask this question on serverfault. If you're simply a programmer who has to deal with it, accept that NAT usually works only from inside to outside and outside to inside, but not inside to inside.
You already mentioned one of the solutions in your question - don't use base_url. You could also simply run the server on an external IP address (not your company IP, but let's say a datacenter or something).