szimek / sharedrop

Easy P2P file transfer powered by WebRTC - inspired by Apple AirDrop
https://www.sharedrop.io
MIT License
9.99k stars 729 forks source link

"same public IP" with IPv6 #55

Open torokati44 opened 7 years ago

torokati44 commented 7 years ago

With IPv6 there is no NAT (most likely), so all devices even on the same local network will have a different "public" IP address. The restriction that this should match for devices in a room does not make sense in this case. I think. The first half of the address is seems like the same, so maybe comparing that would be sufficient?

I know that I could use a "named" room to connect the computers despite this, but transferring the room ID is cumbersome given the fact that the very reason I wanted to use ShareDrop (at this moment) is to easily and quickly transfer a token of similar length between computers.

vovcacik commented 5 years ago

This is a problem with assigning two local users in a same room. It is on server side.

The two users are on LAN and can see each other. If they are put in same ShareDrop room they can transfer files. The problem is that the server detects their IPv6 address which is poor indicator of clients' subnet. As a result both clients are sent to different rooms and they can't exchange files unless a named room is created.

Client A

https://www.sharedrop.io/auth

{
"id":"f8728b00-c301-11e8-975f-cb**********",
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjMyNTAzNjgwMDAwLCJ2IjowLCJkIjp7InVpZCI6ImY4NzI4YjAwLWMzMDEtMTFlOC05NzVmLWNiYjM5Mzg0NmM3MyIsImlkIjoiZjg3MjhiMDAtYzMwMS0xMWU4LTk3NWYtY2JiMzkzODQ2YzczIn0sImlhdCI6MTUzODEyNzM4Nn0.nBDD97wyBhbTqUw6f1d5ne1********************",
"public_ip":"2001:470:6f:197:6101:****:****:****"
}

https://www.sharedrop.io/room

{"name":"1edf5fad8f9a6ad47a4257**********"}

Client B

https://www.sharedrop.io/auth

{
"id":"34a66b40-c303-11e8-975f-cb**********",
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjMyNTAzNjgwMDAwLCJ2IjowLCJkIjp7InVpZCI6IjM0YTY2YjQwLWMzMDMtMTFlOC05NzVmLWNiYjM5Mzg0NmM3MyIsImlkIjoiMzRhNjZiNDAtYzMwMy0xMWU4LTk3NWYtY2JiMzkzODQ2YzczIn0sImlhdCI6MTUzODEyNzkxN30.57rtBPpN8yAQehVWGUL0TM8********************",
"public_ip":"2001:470:6f:197:6cfc:***:****:****"
}

https://www.sharedrop.io/room

{"name":"dccc071de510d541f32c9d**********"}
vovcacik commented 5 years ago

I can see that putting users with exactly same IP in same room is both

Possible solutions that crossed my mind

Immediate workaround

My DNS server can't filter AAAA records per domain, but adding this to /etc/hosts works almost the same:

::0 www.sharedrop.io
tenent007963 commented 3 years ago

A quick add-on: If one of the clients is on different IP version, the whole transfer won't work at all.

Example: Device A: Win 10 PC, on IPv6 Device B: Android 10 phone, on IPv4

When Device A try to send a file to Device B, Device A will try to establish a connection and send a confirmation prompt to Device B, but Device B will show nothing. Same in opposite direction.

Currently the only workaround for the IPv6 issue is to join both devices into same room and both having the same IP version (either upgrade both to IPv6 or downgrade to IPv4).

torokati44 commented 3 years ago

FYI one great thing is that with named rooms the room IDs don't have to be "created" at all. You can basically enter any (reasonable) identifier after https://www.sharedrop.io/rooms/, and you get a room of your own. You don't have to use and transfer that UUID-like random string that is given after creating a room after all. Like: https://www.sharedrop.io/rooms/whateverino, https://www.sharedrop.io/rooms/my-little-room-for-this-project-now or https://www.sharedrop.io/rooms/gimmefiles, and anything similar, will work just fine.

tenent007963 commented 3 years ago

Its still not yet resolved lol.

Maybe can let the auth specifically get the IPv4 IP address instead of getting the newer version IP, since IPv4 is still the major IP version we had all around the world.

szimek commented 3 years ago

PRs are welcome.

As a workaround, one can create a custom room name and use it on all devices, instead of letting the app generate one based on the public IP address.

tenent007963 commented 3 years ago

@szimek Just tried, now custom rooms don't work either. In the console log of the receiving side there's some error:

PeerJS:  Creating RTCPeerConnection. 
waiter-manager.js:24 PeerJS:  Listening for ICE candidates.    

waiter-manager.js:24 PeerJS:  Listening for 'negotiationneeded'    

waiter-manager.js:24 PeerJS:  Listening for data channel     

waiter-manager.js:24 PeerJS:  Listening for remote stream    

waiter-manager.js:24 PeerJS:  Setting remote description RTCSessionDescription {type: "offer", sdp: "v=0\r\no=- 2867090754586875080 2 IN IP4 127.0.0.1\r\ns…:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n"}   

waiter-manager.js:24 Peer:   Opening data channel connection... a {_events: {…}, options: {…}, open: false, type: "data", peer: "d4dbcea9-d33e-4baa-a67f-977490c6c517", …}    

2waiter-manager.js:24 PeerJS:  Added ICE candidate for: d4dbcea9-d33e-4baa-a67f-977490c6c517   

waiter-manager.js:24 PeerJS:  Set remoteDescription: OFFER for: d4dbcea9-d33e-4baa-a67f-977490c6c517   

waiter-manager.js:24 PeerJS:  Created answer.   

waiter-manager.js:24 PeerJS:  Set localDescription: answer for: d4dbcea9-d33e-4baa-a67f-977490c6c517   

3waiter-manager.js:24 PeerJS:  Received ICE candidates for: d4dbcea9-d33e-4baa-a67f-977490c6c517     

waiter-manager.js:24 PeerJS:  ICE connection state is 'disconnected', closing connections to d4dbcea9-d33e-4baa-a67f-977490c6c517    

waiter-manager.js:24 Peer:   Data channel connection error Error: ICE connection state is 'disconnected' at RTCPeerConnection.t.oniceconnectionstatechange [as onicechange] (peer.js:1135)

Suspect might be PeerJS's issue, will try to raise issue at there.

otbutz commented 7 months ago

The two users are on LAN and can see each other. If they are put in same ShareDrop room they can transfer files. The problem is that the server detects their IPv6 address which is poor indicator of clients' subnet. As a result both clients are sent to different rooms and they can't exchange files unless a named room is created.

You could create rooms based on the /64 prefix of IPv6. This is the smallest subnet recommended by the RFCs and roughly the IPv6 equivalent of the shared public IPv4.

otbutz commented 7 months ago

https://github.com/szimek/sharedrop/blob/0418b7894b58576e4c9f3b82228b14c9dbc1006e/server.js#L79

pseudo code:

if (isIPv6(ip)) {
    ip = extractPrefix(ip);
}
const name = crypto.createHmac('md5', secret).update(ip).digest('hex');
otbutz commented 7 months ago

@szimek looks doable via ippaddr.js

const ipaddr = require('ipaddr.js');

var ip = '950b:e036:13c8:3be6:d9cb:b7a3:eccd:3aff'

const addr = ipaddr.process(ip);
if (addr.kind() === 'ipv6') {
  ip = ipaddr.IPv6.networkAddressFromCIDR(ip + '/64').toString();
}

returns 950b:e036:13c8:3be6::

Edit: this is also what paidrop is doing: https://github.com/schlagmichdoch/PairDrop/blob/3fa0873bc4f71f306f0f72afdfecc283bff75b85/docs/host-your-own.md?plain=1#L322-L337