3

I'm trying to figure out if it is possible to have something like this scenario:

Say we have two people, Alice and Bob. Alice wants to send some data (doesn't matter what this data is) to Bob, and vice versa. I know that WebRTC can be used to serverless-ly exchange messages, but that requires Alice and Bob knowing each other's IP addresses. Now, it's relatively easy for Alice and Bob to share their IP addresses once, to initialize a connection, but what happens if one of them happens to connect to a different network; maybe Bob is in a coffee shop, for instance, and his IP address is thus different? The previously initialized connection wouldn't be to his current IP address, so they'd have to reinitialize the connection; but how?

It would seem to me that there would already need to be some sort of preexisting communication between the two so they could share their IP addresses, but then why not just communicate through the method they communicate their IP addresses instead? Alternatively, there could be a server that connects the two, but that defeats the serverless part of the system.

So, is there any way to maintain communication between two clients even if they happen to change networks, and thus IP addresses? Perhaps there is a more fixed method of identifying devices than their IP addresses, like I've seen in this SO answer, but it's years old, so maybe there's something new? I'd be implementing this in JS, across multiple devices/OSs, so that answer probably wouldn't work. Any ideas/examples would be greatly appreciated; I mainly want to know if this is even possible, and, if so, how.

marsnebulasoup
  • 2,530
  • 2
  • 16
  • 37
  • Perhaps you need a centralised server that they connect to first, that will establish their IPs? Unless you're trying to avoid this kind of system. – Mike Stoddart Dec 10 '20 at 17:51
  • 1
    Yeah, I'm hoping it's possible without a centralized server. The clients can use other mediums to initialize the connection/share information in the beginning, but that would be the only time they do so. – marsnebulasoup Dec 10 '20 at 17:54

3 Answers3

6

Simple Answer

No, while this is possible, it is unrealistic and not needed. See my longer explanation below. Also, if you really want to do this, although it is possible through QUIC, it’s not likely to be needed (as explained below).

Longer Answer/Question to think about

In short, this is not a needed feature of WebRTC. Let me ask you a question:
Alice and Bob are in a data channel, exchanging chat messages over WebRTC. To create a WebRTC connection, you need to use an ice server ( first link, second link ) to get both Alice and Bob to, to quote Wikipedia:

...to find ways for the two computers to talk to each other as directly as possible..

This means that it will use Alice’s current IP address to make an offer to Bob through a STUN or TURN server. If, like you said, Alice were to change IP addresses, she would need to change location. That means that she will need to move a sufficient distance so that the IP address will change. In practice, this probably means that she goes in a car and drives somewhere. If not, she calls an Uber or a cab or rides her bike. In most of these scenarios, she will need to close her computer, hence ending the p2p connection. If, by some weird wizardry, she doesn’t close her computer/the connection, the browser will very likely refresh, hence re-connecting to the WebRTC data channel from the new IP address. When will you need to create a WebRTC data channel and handle IP changes? Long explanation coming to a conclusion, clients changing IP addresses without ending/resetting the connect just doesn’t happen in practice.

If you want to look into other alternatives, here are some examples:

ALTERNATIVES

Adding an IP event listener ★

Now this isn’t an actual global variable that you can check, but you can use an online API (some are listed here) to check the user’s IP address, store it in a variable (or localStorage), and check if the IP changes. In a loop, you would do some simple logic to check If it does, you reset the WebRTC connection, if not, you keep the loop going.

Using a “piping” server

You can set up a simple chat by using a http/https server, already set up, explained here, called a piping server. You can look at the article for more information, but it promotes a serverless chat system (can be used without creating a server) that isn’t exposed to the difficulties of changing IP addresses. However, you need to know the peer’s ID, and they need to know your ID, which effectively makes solution obsolete because you need to have some sort of communication before establishing this simple chat.

Using Node.js, Websockets, and/or Socket.io ★

If you want to create a simple chat app or create a data channel, Node.js and Socket.io is the way to go. This is super simple, however, it involves a server, which is why I left it for last. However, I highly recommend this for ease and simplicity, and is not reliant on IP addresses. See here for a very good starting immersion into Node.js and the Express framework. I am far from an expert from Websockets, but MDN is always a good place to start. However good Websockets are, I think that Socket.io is much easier for beginners, so if you are willing to sacrifice a bit of speed over simplicity, you should start here. These are all good server-side chat starting points.

Links

Simple Answer

QUIC connection migration

IP Listener

SO Question,

Ice Servers

MDN docs, Wikipedia

Piping Server

Simple article, Github repo

Node.js, Websockets, and Socket.io

Node.js and Express setup, Websocket intro, and Socket.io intro

All alternatives that are starred (★) are personally recommended.

divinelemon
  • 1,925
  • 2
  • 23
  • 1
    Wow! This is a very in-depth answer, really helped me on a project I am working on. Take my +1! – imaginate Dec 14 '20 at 23:08
  • @divinelemon - First of all, thank you for your in-depth answer. From what I understand of WebRTC, to connect to each other, peers need to know each other's IP address to establish a connection. If a connection is established initially between Alice and Bob by sharing their IP addresses somehow (initially, it doesn't matter), and they communicate, and later disconnect when finished, is it possible for them to reconnect without sharing their IP addresses with each other, or, what info would they have to share the first time they connect to be able to establish the connection later on? – marsnebulasoup Dec 16 '20 at 18:59
  • I don't see how this is possible if they move to different locations, as their IP addresses would be different, and they wouldn’t know each other’s new IP addresses. The idea that there is a server that establishes connections between the peers (the peers would update the server with their current IP when they connect to a different network), but does not actually handle any data transfer, seems to be the only option I can see. I'm not too concerned with maintaining the *same* connection between peers if one or both of their… – marsnebulasoup Dec 16 '20 at 18:59
  • ...IP addresses change (I now realize that my question title might have been a bit ambiguous), but rather, I'm looking for a way to reestablish that connection without the peers actually knowing each other's new IP addresses. Your IP event listener solution seems interesting, but how would the WebRTC connection reconnect (or connect again later if intentionally disconnected), if the peers don't know if the other has moved to a different network? – marsnebulasoup Dec 16 '20 at 18:59
  • @cybercoder's idea, (or at least a custom server that would store peers' current IP addresses), to connect both seems to get around this problem, but I don't suppose there is really any other way to reconnect the two peers later on with just the data used to initialize the connection in the first place; but maybe it’s possible by using a piping server to share the needed WebRTC connection info, so that the peers would only need to know each other's ID and wouldn't have to actually communicate through the server itself (besides the connection info). Would that be feasible? – marsnebulasoup Dec 16 '20 at 18:59
  • @marsnebulasoup Sorry for not responding in time for the bounty, I have been very busy working on a couple of projects. Thank you for your comments, they help me understand what you want. You do not need any of these solutions then, the standard solution to get each peers' IPs is to use an ICE server/STUN/TURN. The way to reconnect the two peers later on would be to use something like a piping server, however, in production, I do not recommend using one, instead use something like websockets. Getting back to the initial question however, I do not think it is possible to reconnect each peer ... – divinelemon Jan 19 '21 at 21:47
  • .. to each other without using something like a piping server that only takes the ID of the user. However, in the long run, you are going to want to use a server to completely control the data of all requests, and using a server also exposes great tools like WebSockets among others. In reply to your last question, it would be entirely feasible to use a piping server to share the ICE candidates request and other WebRTC information, that is basically what happens with a "normal" Socket.io/WebSockets chat and works perfectly. – divinelemon Jan 19 '21 at 21:50
  • Please ask me if you have any questions. I hope this helps you along on your WebRTC journey! :) – divinelemon Jan 19 '21 at 21:51
  • 1
    Note that if you use a smartphone these days and you move around with it (from your home -> to your car -> then to your workplace) it's perfectly conceivable that your IP will change multiple times. As years go by this scenario becomes more and more common. – XDS Jan 17 '22 at 09:01
  • 2
    @XDS exactly, this is very common especially in scenarios where the phone automatically switches from cellular to wifi. – divinelemon Jan 17 '22 at 16:59
3

Yes, It is possible.

You need to use FQDN (or a sub-domain) instead of IP Address and a DNS server, and a client side util or tool to update DNS record while IP Address changing.

There's free solutions on the web like no-ip.com, cloud-flare and etc.

Vahid Alimohamadi
  • 4,900
  • 2
  • 22
  • 37
-1

A more modern approach to this would be using QUIC for transport. It has a session ID in the payload and uses UDP as the transport. This handles the very common case where a NAT will change it's Public IP. From Cloudflare's blogpost:

One of the features QUIC is intended to deliver is called “connection migration” and will allow QUIC end-points to migrate connections to different IP addresses and network paths at will.

So assume Alice and Bob are sending messages via QUIC and their connection is given a session ID. Alice's NAT changes it's public IP and source port. Since UDP is being used, Alice's messages still are being sent to Bob's Public IP. Bob receive these UDP messages and looks at the embedded QUIC header and sees that it contains the same session ID as when he was speaking to Alice. Bob then starts using Alice's new public IP and port as a destination for the conversation.

Naturally this seems open to redirection attacks, but there is crypto layered on top of these mechanisms to prevent this and other attacks.

References:

Liam Kelly
  • 3,524
  • 1
  • 17
  • 41