Recent

Author Topic: Korg Remote Desktop  (Read 9503 times)

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Korg Remote Desktop
« on: November 11, 2020, 09:40:57 pm »
Hi guys, here is a first almost usable version of Korg Remote Desktop (KRD).

www.lazaruspascal.it/download_personali/korg_remote_desktop.zip

I started this project hoping to learn as much as possible in creating a software similar to "Team Viewer".
Of course KRD is open source and for the moment tries to manage everything with UDP broadcasts.
In addition to the sources already compiled for the following platforms.

linux 64 bit (ubuntu)
win 32 bit
win 64-bit
mac os x 64 bit (cocoa)

The source has the following dependencies

LCL
laz_synapse
dcpcrypt
LazMouseAndKeyInput (if you use cocoa, use the version you find at this link: www.lazaruspascal.it/download_personali/mouseandkeyinput_cocoa_support.zip)

Seguono le "custom options"
 -dUseCThreads            : required for multithreading to work
 -dWriteDebug             : write exceptions to terminal when they occur (mainly for debugging)
 -dGetScreenInMainThread  : it is used to get the screen content from the main thread and not from the secondary ones. This is because on ubuntu if I don't use this option it makes me crash the program
 -dMyVersion              : always
 -dSendWithMemory         : used to send data as tmemory and not as tstring
 -dSendWithCompression    : used to compress memories (never)
 -dFilterFromIpPort       : always     

At startup the program tries to establish its own ip address both local (it works only for win, other operating systems always report 127.0.0.1) and remote (does not use udp in this case). It is just for testing faster.

At present it works fine in the local network (I hoped it would also work with clients on the internet (because I thought I had correctly implemented UDP Hole Punching, but my few tests in this regard have proved me wrong)

If you open the program you will see a value "123Pwd456", it coincides with the password to encrypt the connections (aes 128 bit). If you remove the password, everything will be transmitted in clear text.

Test hypotheses

Client "A" who wants to share their desktop (ip: 192.168.1.6)
I open the program, I press the "invert" button, then change the remote ip with the value "192.168.1.11", then I press the "start" button. The program will end up in the System Tray

Client "B" who wants to access the remote desktop (ip: 192.168.1.11)
I open the program, change the remote ip with the value "192.168.1.6" and press the "start" button

You should now see the first results. At present the program has the following limitations

1. only handles udp broadcasts and udp hole punching doesn't work (someone network expert who helps me solve the mystery)
2. the use of the keyboard and the mouse is not optimized (for example the dragging of a remote window does not work, while the click and the double click would seem to be).
3. I have yet to implement file transfer
4. I have yet to implement the transfer of clipboard content.

Advice and help are welcome. I develop the program only for study, but if over time it worked well, I do not deny that I could also use it to completely supplant other programs of the kind and not have to pay licenses for them anymore.
KRD is open source and will always remain open source.
« Last Edit: November 11, 2020, 09:42:56 pm by xinyiman »
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #1 on: November 12, 2020, 06:58:58 pm »
I understand what I'm wrong. I haven't implemented UDP Hole Punching correctly.
There is still no "controller" software that can always be reached. On the weekend I implement it if I can and then update you. Meanwhile, if someone wanted to give me feedback on the work in lan I would be really happy.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

MarkMLl

  • Hero Member
  • *****
  • Posts: 7999
Re: Korg Remote Desktop
« Reply #2 on: November 12, 2020, 07:12:59 pm »
Remember that UDP broadcasts normally don't go through a router. At the very least, you'll need to make sure that all cooperating systems are (a) aware of all subnets to which they're attached (b) tell all other cooperating systems on all subnets that they're alive and (c) pass queries between subnets intelligently. You're strongly advised to not simply rebroadcast queries unless you have time-to-live provision in your protocol, since otherwise you WILL get loops causing a packet storm.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #3 on: November 15, 2020, 05:01:33 pm »
Here I am, I just wanted to warn you that I have not updated the software as I said. I made some changes, but failed to implement UDP Hole Punching.
I created the server controller (which works correctly) because it allows connected clients to obtain the ip and ports of remote clients, but when I try to establish the connection it doesn't work. I'm starting to get desperate because I've spent all weekend on it without pulling a spider out of the hole.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #4 on: November 15, 2020, 05:12:05 pm »
There is one thing I don't understand. Let's assume I have the two clients that have already exchanged information via the controller. Let's assume that client A has an ip address 23.6.141.2 and port 5000 while client B has an address 35.7.121.15 and port 1926.

Client A starts sending packets to 35.7.121.15:1926
Client B starts sending packets to address 23.6.141.2:5000

then each of the clients listens and receives the packets it sent.
Client A receives packets generated by 35.7.121.15:1926
Client B receives packets generated by 23.6.141.2:5000

But I don't understand how this can happen.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

MarkMLl

  • Hero Member
  • *****
  • Posts: 7999
Re: Korg Remote Desktop
« Reply #5 on: November 15, 2020, 05:39:22 pm »
What don't you understand? UDP is a connectionless protocol: you've got programs associated with the host's IP number and with a given port.

The program sends from that IP address and port.

The program is also listening for traffic on that IP address and port.

You can't have two programs on the same host listening to the same address:port doublet.

When the program receives a packet, it must also recover the IP address and port of the sender. That identifies the sender, hence it knows where to send a reply.

You obviously either need some "well known" port to start a session, or you need to use some other communication path e.g. an SMS text message.

MarkMLl


MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #6 on: November 16, 2020, 07:32:01 pm »
Hello to all. I think I understand the problem. My program works, the problem is that my NAT is bidirectional.
In a non-bidirectional nat type when client A connects to the controller it communicates ip and port which will be communicated to client B and everything will work, because client A will always use that ip and that port.
In a bidirectional nat the port communicated to the controller is different from the one used for P2P with client B. Now I have thought about it a little, and it would seem that I only have two ways.

1. Client A does a full port scan of client B until I can pair the communications between the clients.
2. I ask the router for the NAT table for my connections (I have no idea how to do it)

I ask if in your opinion there are alternative ways or if you help me to realize point 2.

thanks a lot
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #7 on: November 16, 2020, 07:52:11 pm »
1. Client A does a full port scan of client B until I can pair the communications between the clients.
2. I ask the router for the NAT table for my connections (I have no idea how to do it)
You shouldn't do 1. You're likely to be blocked by the router for doing a port scan.

I'm I direct in thinking you want to connect two clients outside each others network without a middle man (connector like in teamviewer)?

Even with whole punching with a connector it could be that the router doesn't allow this. With whole punching both computers send a packet to the connector after which the connector can tell each client what port they are listening to. But some routers only allow external_ip:port combination so the traffic can only come from the connector (and not from any other random client). And if the router does allows it I think you still need the connector be the initiator for the connection.

https://en.m.wikipedia.org/wiki/UDP_hole_punching

Another option would be to use upnp. If that's enabled on the router it's relatively easy to add an entry in the router (just like a port foward). You van did that in code yourself or use some tool to add the upnp entry (for example miniupnpc for linux).
« Last Edit: November 16, 2020, 07:54:12 pm by rvk »

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #8 on: November 16, 2020, 08:00:18 pm »
1. Client A does a full port scan of client B until I can pair the communications between the clients.
2. I ask the router for the NAT table for my connections (I have no idea how to do it)
You shouldn't do 1. You're likely to be blocked by the router for doing a port scan.

I'm I direct in thinking you want to connect two clients outside each others network without a middle man (connector like in teamviewer)?

Even with whole punching with a connector it could be that the router doesn't allow this. With whole punching both computers send a packet to the connector after which the connector can tell each client what port they are listening to. But some routers only allow external_ip:port combination so the traffic can only come from the connector (and not from any other random client). And if the router does allows it I think you still need the connector be the initiator for the connection.

https://en.m.wikipedia.org/wiki/UDP_hole_punching

Another option would be to use upnp. If that's enabled on the router it's relatively easy to add an entry in the router (just like a port foward). You van did that in code yourself or use some tool to add the upnp entry (for example miniupnpc for linux).

Yes that's right, I try to replicate how teamviewer works to understand how it works. I'll try with upnp, taking the time to read up to understand how it works. Thanks for your advice.

Obviously if you have to "scan the ports", start from those close to those used for communication with the controller. However, it does not mean that it opens its doors consecutively.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #9 on: November 16, 2020, 08:33:32 pm »
The problem with hole punching is that if you send out a package on port 5000 for instance, the public port which is opened for return traffic can be anything. That's why the middle man is needed.
Maybe it's better explained in the answer here.
https://unix.stackexchange.com/questions/421471/udp-or-tcp-hole-punching-to-connect-two-peers-each-one-behind-a-router

Sometimes the public port is the same as the internal port and your in luck. But usually the port is also translated to another port by the NAT.

But I found this where it states a technique where is not needed.
https://github.com/samyk/pwnat

You could see how it's done there.

PS. Upnp is easy to do but it needs to be enabled in the router. Sometimes it's standard enabled but for security there are also lots of routers which have it off by default. If you have a large userbase where you med to implement this, unpnp might not be the choice unless you can controll that setting.

A third party server (connector) is the best way to do hole punching.




MarkMLl

  • Hero Member
  • *****
  • Posts: 7999
Re: Korg Remote Desktop
« Reply #10 on: November 16, 2020, 10:01:06 pm »
1. Client A does a full port scan of client B until I can pair the communications between the clients.

As others have said: don't.

Quote
2. I ask the router for the NAT table for my connections (I have no idea how to do it)

You might be able to do it from the local side, but if it can be done from the Internet side it indicates a MASSSIVE security problem.

On the local side there's a modicum of standardisation around SNMP to do this, at least on reputable routers... I've done quite a lot of poking around on Draytek routers using SNMP.

I'd remind you that early conferencing systems like CU-SeeMe specifically had a central "reflector". I'd also remind you that most current conferencing systems have something comparable (e.g. AIUI Skype has servers run "in the cloud" by MS). My experience is that VOIP relies on pre-opened UDP "holes" available to whoever is providing the POTS gateway (e.g. Gamma in the UK), I've not explored more esoteric possibilities (it's bad enough without getting esoteric).

If you were using a PC as a router you could probably do something adequate with port knocking. You'd also be entering, as they say, a whole area of pain.

See my previous comments about discovery, but I think that as an absolute minimum you need some central node to accumulate information about what port etc. each site is using. You might in practice also have to "reflect" traffic though it... I've done a lot of this UDP stuff but it has been internal rather than also having to contend with arbitrary NATting.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #11 on: November 17, 2020, 08:41:59 am »
The problem with hole punching is that if you send out a package on port 5000 for instance, the public port which is opened for return traffic can be anything. That's why the middle man is needed.
Maybe it's better explained in the answer here.
https://unix.stackexchange.com/questions/421471/udp-or-tcp-hole-punching-to-connect-two-peers-each-one-behind-a-router

Sometimes the public port is the same as the internal port and your in luck. But usually the port is also translated to another port by the NAT.

But I found this where it states a technique where is not needed.
https://github.com/samyk/pwnat

You could see how it's done there.

PS. Upnp is easy to do but it needs to be enabled in the router. Sometimes it's standard enabled but for security there are also lots of routers which have it off by default. If you have a large userbase where you med to implement this, unpnp might not be the choice unless you can controll that setting.

A third party server (connector) is the best way to do hole punching.

Evidently I have not explained myself well.
I have an intermediary that I call controller that is started on a server with a public ip address that is always reachable.

When client A connects to the controller it communicates its ip address and port to the controller.

When client B connects to the controller it communicates its ip address and port to the controller.

Now A asks for information from B and B asks for information from A.

So far everything works. It is a pity that the information obtained is not that which allows A and B to establish a P2P connection. Because bidirectional NAT means that when A tries to connect to B it uses a different port than the one used to connect to the controller.

So my intermediary is not much use in this case, if only to get the right ip but the port is wrong.

In the case of pwnat I understand that it does not generate a P2P connection but that the data passes through the proxy (a different scenario from mine).
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

MarkMLl

  • Hero Member
  • *****
  • Posts: 7999
Re: Korg Remote Desktop
« Reply #12 on: November 17, 2020, 08:52:33 am »
So far everything works. It is a pity that the information obtained is not that which allows A and B to establish a P2P connection. Because bidirectional NAT means that when A tries to connect to B it uses a different port than the one used to connect to the controller.

As would be expected: it's a different session with a different endpoint.

I've obviously been wasting my time explaining that you either need to keep a reflector in the link or need to have preexisting pinholes open (which realistically implies that the endpoints are known), so I won't bother saying anything else.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

rvk

  • Hero Member
  • *****
  • Posts: 6572
Re: Korg Remote Desktop
« Reply #13 on: November 17, 2020, 08:55:48 am »
I have an intermediary that I call controller that is started on a server with a public ip address that is always reachable.

When client A connects to the controller it communicates its ip address and port to the controller.

When client B connects to the controller it communicates its ip address and port to the controller.

Now A asks for information from B and B asks for information from A.

So far everything works. It is a pity that the information obtained is not that which allows A and B to establish a P2P connection. Because bidirectional NAT means that when A tries to connect to B it uses a different port than the one used to connect to the controller.
That makes it a lot easier.

Did you send the EXTERNAL port of side A to client B?

You can't use the port A uses for outgoing. The EXTERNAL port for A is random.

The controller sends EXTERNAL port of A to B and EXTERNAL port of B to A.
On those ports A and B can communicate directly.

(Only the controller knows the random EXTERNAL ports of A and B and needs to give those to the other client)

Please read the first 3 steps under "Flow" on this page carefully.
https://en.m.wikipedia.org/wiki/UDP_hole_punching
« Last Edit: November 17, 2020, 09:08:00 am by rvk »

xinyiman

  • Hero Member
  • *****
  • Posts: 2256
    • Lazarus and Free Pascal italian community
Re: Korg Remote Desktop
« Reply #14 on: November 17, 2020, 09:15:24 am »
I have an intermediary that I call controller that is started on a server with a public ip address that is always reachable.

When client A connects to the controller it communicates its ip address and port to the controller.

When client B connects to the controller it communicates its ip address and port to the controller.

Now A asks for information from B and B asks for information from A.

So far everything works. It is a pity that the information obtained is not that which allows A and B to establish a P2P connection. Because bidirectional NAT means that when A tries to connect to B it uses a different port than the one used to connect to the controller.
That makes it a lot easier.

Did you send the EXTERNAL port of side A to client B?

You can't use the port A uses for outgoing. The EXTERNAL port for A is random.

The controller sends EXTERNAL port of A to B and EXTERNAL port of B to A.
On those ports A and B can communicate directly.

(Only the controller knows the random EXTERNAL ports of A and B and needs to give those to the other client)

Please read the first 3 steps under "Flow" on this page carefully.
https://en.m.wikipedia.org/wiki/UDP_hole_punching

Of course, the controller communicated the data from client A to client B and vice versa. But when client A communicates with the outgoing controller it uses port 1900 (example) of the router when instead it has to create the P2P connection with client B it uses port 1901 (example) due to bidirectional nat (change port based on destination ). Then the port communicated to the controller becomes useless.
Win10, Ubuntu and Mac
Lazarus: 2.1.0
FPC: 3.3.1

 

TinyPortal © 2005-2018