n2n icon indicating copy to clipboard operation
n2n copied to clipboard

It is recommended to merge edge and sn into the same executable program

Open fengdaolong opened this issue 4 years ago • 13 comments

edge and sn have a lot of the same redundant code. I suggest to merge them into a separate main program. The name after construction is called n2n. Like openvpn, it uses parameters to declare whether it is a server or a client. n2n can add a parameter to declare that it is running in the sn state, and if no parameter is added, the default is to run in the edge state. The independent executable file improves the convenience of n2n. If static compilation is used, then a single program can accomplish everything.

Please comment!

fengdaolong avatar Jul 18 '20 05:07 fengdaolong

I like that idea!

However, some might object against the possibly bigger file size in supernode-only use-cases.

Logan007 avatar Jul 18 '20 12:07 Logan007

Yes, there must be sacrifice. So we need to discuss whether we can do this together.

fengdaolong avatar Jul 18 '20 12:07 fengdaolong

In a very first approach, some n2n.c containing a new main() could be created. It evaluates argv[] to decide which of the original main()s is to be called along with the argc and argv[]. The original main()s could be renamed to sn_main() and edge_main().

Very hacky, I admit… Also, the help texts need to be synthesized in that new n2n.c.

At a first glance, I do not see any more potential for combining the main loops in their current form beyond the above sketched.

P. S. There is just one issue with this: Unfortunately, the supernode cli-parameters -c and -l are meaningful to the edge as well. So how could the two functionalities be distinguished?

Logan007 avatar Jul 20 '20 19:07 Logan007

In a very first approach, some n2n.c containing a new main() could be created. It evaluates argv[] to decide which of the original main()s is to be called along with the argc and argv[]. The original main()s could be renamed to sn_main() and edge_main().

We can add a file named "n2n_main.c".

Very hacky, I admit… Also, the help texts need to be synthesized in that new n2n.c.

Regarding the modification of the help document, my English is very poor😧, so I rely entirely on Google translation. I think you can do this because you are the best 👍👍👍!

P. S. There is just one issue with this: Unfortunately, the supernode cli-parameters -c and -l are meaningful to the edge as well. So how could the two functionalities be distinguished?

It can add a parameter, which has the highest priority. When checking the existence of this parameter, it runs as a supernode, otherwise, it is an edge. However, I really can't think of better parameters, because the most suitable parameters have been used, such as (s)erver, (m)ain, (c)enter... Another method is to determine its own file name, and run as what its own name is (edge or supernode).

fengdaolong avatar Jul 21 '20 06:07 fengdaolong

I would not want to add another parameter... the new main needs to decide whether to run as edge or supernode just by the parameters present. Luckily, -c and -l are not the only ones required to run the edge.

But does it make sense to have -c and -l parameters with different meanings depending on the rest of the parameters, i.e. edge or supernode mode?

The filename-based method seems a bit complicated to explain to users. It would require renaming, duplicating or soft/hard links.

Logan007 avatar Jul 21 '20 08:07 Logan007

But does it make sense to have -c and -l parameters with different meanings depending on the rest of the parameters, i.e. edge or supernode mode?

I agree to use the -l parameter to distinguish.

fengdaolong avatar Jul 21 '20 10:07 fengdaolong

It can be used on n2n_v3 for auxiliary supernodes.

lucktu avatar Jul 25 '20 14:07 lucktu

Now that n2n has changed a lot, some command line parameters are not compatible with the old version. We need to make a complete change, no longer consider compatibility, merge supernode and edge, and redefine the original conflicting parameters of supernode and edge. From then on, each edge enables listening on the supernode port by default at runtime, and the listening port can be negotiated by each running edge. what do you think? @Logan007

fengdaolong avatar Nov 08 '20 10:11 fengdaolong

After the supernode and edge are merged, dual threads can be opened to run the program, the supernode and edge each occupy one thread, they share memory data and run in separate threads.

fengdaolong avatar Nov 08 '20 10:11 fengdaolong

no longer consider compatibility

and redefine the original conflicting parameters of supernode and edge

There is an effort to do that. Actually, it only hits the -l and -p parameter which shall be used in the same way on edge as well as on supernode:

-l <supernode ip address:port gives a supernode to edge and supernode -p <udp port> provides the ud listen port

Luckily, we already have some more similarities such as -t and -u/-g. Do you have suggestions for more harmonization work to be done in this regard?

I know that not everybody is too happy with changing command line parameters, especially, as before, -l was to indicate the udp port at the supernode side and users will have to change their start-up scripts after updating. We need to make this information stand out in the Readme.md file and guide users through this change as soon as 3.0 gets closer (I have not idea when that will be).

merge supernode and edge

As I said at some other occasions, a lot of changes coming up with the federation approach which currently is under implementation already pushes n2n into that direction. This approach starts seeing supernodes as other nodes (with own MAC addresses now) that can be organized in a community (called federation in this case), too. My far-far-future aim still is treat every edge/supernode/node equal (including sharing the same binary) – some just having special properties such as pubic IP to help others do the hole punch. I am not sure how we can accelerate this step-wise development any further.

From then on, each edge enables listening on the supernode port by default at runtime, and the listening port can be negotiated by each running edge.

I am not sure if I fully understand this idea. Could you elaborate on that?

After the supernode and edge are merged, dual threads can be opened to run the program, the supernode and edge each occupy one thread, they share memory data and run in separate threads.

This is an intermediate step which I honestly think could even be omitted. I would not merge by forcing the binaries with their (still) different functionalities into two parallel threads. I would go the merger way by blending the packet formats, e.g. starting with the REGISTER and REGISTER_SUPER packets. For now, they serve two purposes: To acquaint nodes to each other (of which one could be a supernode) and also to find out about current/better ways to communicate (p2p through the REGISTER_ACK).

This view on the packets could generalized a bit by saying: Let's use a REGISTER packet to acquaint nodes, no matter if they have an own tun/tap or a public IP address.

Logan007 avatar Nov 08 '20 11:11 Logan007

In actual use, the change of edge parameters is far greater than the impact of supernode parameter changes, so we only change the supernode parameters and keep the edge unchanged. After merging the supernode into the edge, the command line parameters of the supernode suggest:

-p <port> | Set UDP main listen port to <port> -c <path> | File containing the allowed communities. -l <sn host:port> | Name/IP of a known supernode:port. -F <fed_name> | Name of the supernodes federation (otherwise use '*Federation' by default) -m <mac_addr> | Fix MAC address for the supernode (otherwise it may be random) | eg. -m 01:02:03:04:05:06 -u <UID> | User ID (numeric) to use when privileges are dropped. -g <GID> | Group ID (numeric) to use when privileges are dropped. -t <port> | Management UDP Port (for multiple supernodes on a machine). -a <net-net/bit> | Subnet range for auto ip address service, e.g. | -a 192.168.0.0-192.168.255.0/24, defaults to 10.128.255.0-10.255.255.0/24 -v | Increase verbosity. Can be used multiple times. -h | This help message.

-p Change the parameter character, such as "-P". Only the port specified by the default initial supernode is valid. If the current working supernode changes, it will be decided through negotiation, and all supernodes and edges will be notified. -c Change the parameter character, such as "-P". Only the content specified by the default initial supernode is valid. If the current working supernode changes, it will be decided through negotiation, and all supernodes will be notified. -l Combined with the -l parameter of edge. -F Constant. -m Combined with the -m parameter of edge. -u Combined with the -u parameter of edge. -g Combined with the -g parameter of edge. -t Use other characters. -a Use other characters. -v Combined with the -v parameter of edge. -h Combined with the -h parameter of edge.

fengdaolong avatar Nov 08 '20 11:11 fengdaolong

I am not sure if I fully understand this idea. Could you elaborate on that?

What I mean is that when supernode and edge merge, suppose I call it n2n_main, then as long as n2n_main is started, it will automatically start edge and supernode functions at the same time and listening the port of supernode. It has both the role of edge and supernode, but its supernode role is on standby in the federation.

fengdaolong avatar Nov 08 '20 11:11 fengdaolong

but its supernode role is on standby in the federation

That is exactly what I have in mind but again, not by merging the binaries but merging functionalities. With a future true p2p-approach, every node shall provide the same functionalities. That would include the supernode functionality. The way I start seeing a supernode these days is that it basically is a node like edge node featuring the following differences:

  • it (usually) lacks the local tun/tap device – some might have edge in parallel for local outlet
  • it definitely has a public IP address
  • it knows a path to all other nodes (as all other nodes register to it)

It is those properties that result in its special functions such as

  • being the hole-punching helper which includes
  • packet forwarding if no other way available

Logan007 avatar Nov 08 '20 11:11 Logan007