-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support nconnect network feature #71
Conversation
admin/server.go
Outdated
@@ -10,6 +10,12 @@ import ( | |||
tunnel "github.com/nknorg/nkn-tunnel" | |||
) | |||
|
|||
var networkMemberIAccept []string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't recommend using global variable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
admin/server.go
Outdated
continue | ||
} | ||
|
||
var perm permission | ||
if isAcceptAddr { | ||
if isAcceptAddr || isNetworkMemberAddr { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should separate the permissions of accept addr and member addr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
arch/tun_test.go
Outdated
dnsServers := []string{"192.168.0.1"} | ||
persist := false | ||
|
||
OpenTunDevice(name, addr, gw, mask, dnsServers, persist) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only works on Windows and Mac but not Linux. Check the tun code for different platforms
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, got it.
config/config.go
Outdated
@@ -123,6 +125,10 @@ type Config struct { | |||
lock sync.RWMutex | |||
AcceptAddrs []string `json:"acceptAddrs"` | |||
AdminAddrs []string `json:"adminAddrs"` | |||
|
|||
// nconnect network | |||
NodeName string `json:"nodeName,omitempty" long:"node-name" description:"Node name, will be used as nConnect network node name"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(network member only) Node name that will be used as to join a network
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
config/config.go
Outdated
|
||
// nconnect network | ||
NodeName string `json:"nodeName,omitempty" long:"node-name" description:"Node name, will be used as nConnect network node name"` | ||
ManagerAddress string `json:"managerAddress,omitempty" long:"manager-address" description:"Manager address, will be used as nConnect network manager address"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(network member only) Manager address to connect to when joining a network
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
TunaGeoDBPath: opts.TunaGeoDBPath, | ||
TunaMeasureBandwidth: !opts.TunaDisableMeasureBandwidth, | ||
TunaMeasureStoragePath: opts.TunaMeasureStoragePath, | ||
TunaMeasurementBytesDownLink: opts.TunaMeasureBandwidthBytes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't modify this section. Maybe keyboard mistake. let me recover it.
err := nc.opts.VerifyClient() | ||
if err != nil { | ||
return err | ||
if !nc.opts.NetworkMember { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say we put this if inside VerifyClient()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VerifyClient is a method of Config, and it can't get the mode(client, server, or network) of nConnect. An alter way is to put VerifyClient into Opts.
util/util.go
Outdated
// If paramenter port is 0, start from system returned free port | ||
// The returned port is free in TCP and UDP | ||
func GetFreePort(port int) (int, error) { | ||
for i := 0; i < 100; i++ { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
retry without sleep is not likely to make a difference. We should add sleep (but also reduce the number of retries so it won't take forever)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here each retry will increase port. Such as we first retry 1080, if it is busy, then try 1081, 1082, ... until we get a free port. Is it suitable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is the code to increase port? And since you don't need a fixed port, why not a random dynamic port?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when UDP listen fails, the port will be increased to try the next port. if argument port
=0, it will try a random dynamic port. This modification expands the use cases of this function: 1. get a free port from system random port; 2 get a specific port or subsequent port, such as 1080, 1081, ...
if err != nil { l.Close() port++ continue }
nconnect.go
Outdated
nc.ssClientConfig.Client = from[0] | ||
nc.ssClientConfig.DefaultClient = from[0] // the first config is the default client | ||
} else { | ||
nc.ssClientConfig.Client = "127.0.0.1:0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should mean start ss with a random port right? Or you don't want ss at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ssClientConfig.Client is just a condition for starting ss client. Before we support multi-tunnels, its value is the from
source of the tunnel. Now we support multi-tunnel, the from
sources will be gotten from the target IP. so ssClientConfig.Client 's value is only for starting client now. the condition is:
if flags.Client != "" { // client mode
nconnect.go
Outdated
|
||
log.Println("Client socks proxy listen address:", nc.opts.LocalSocksAddr) | ||
|
||
if nc.opts.Tun || nc.opts.VPN { | ||
tunDevice, err := arch.OpenTunDevice(nc.opts.TunName, nc.opts.TunAddr, nc.opts.TunGateway, nc.opts.TunMask, nc.opts.TunDNS, true) | ||
tunDevice, err := arch.OpenTunDevice(nc.opts.TunName, nc.opts.TunAddr, nc.opts.TunGateway, nc.opts.TunMask, nc.opts.TunDNS, false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI persist option only works on Linux. On Mac/Win it's not used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. let me restore it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean you can still use it if needed, but you need to make sure the changes will work on all platforms we support
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks for the advice.
nc.waitForSignal() | ||
|
||
return nil | ||
} | ||
|
||
func (nc *nconnect) startSSAndTunnel() { | ||
func (nc *nconnect) startSSAndTunnel(client bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend we pass in the config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
nconnect.go
Outdated
} | ||
ssAddr := "127.0.0.1:" + strconv.Itoa(port) | ||
|
||
toAddr := strings.Replace(addr, "client.", "", -1) // remove network member's client. prefix, it should be server's address |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have to assume the address format here? Why can't we just store and use other members' tunnel address directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified. The nconnect server's listen address is registered to the network manager and notified to the network authorized members.
nconnect.go
Outdated
|
||
toAddr := strings.Replace(addr, "client.", "", -1) // remove network member's client. prefix, it should be server's address | ||
adminAddr := nc.opts.AdminIdentifier + "." + toAddr | ||
if remoteInfo, err := nc.getRemoteInfo(adminAddr); err == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For network mode, why we need to use other members' local IP at all? We should use the assigned IP address, which doesn't need getRemoteInfo at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
nconnect.go
Outdated
|
||
if len(from) > 0 { | ||
identifier := config.RandomIdentifier() | ||
tunnels, err := tunnel.NewTunnels(nc.account, identifier, from, to, nc.opts.Tuna, nc.tunnelConfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, so we are creating a new client each time we update the access address?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I will modify nkn-tunnel
to reuse multi-client.
network/manager.go
Outdated
|
||
const ( | ||
defaultDomain = "nconnect.nkn" | ||
defaultIpStart = "192.168.0.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't use 192.168 by default, this IP range conflicts with too many routers. I would use 10.X.Y range with a rarely used X and Y
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified. It is configurable on the manager's web page too.
network/message.go
Outdated
return nil, err | ||
} | ||
|
||
func GetMultiClient(opts *config.Opts) (*nkn.MultiClient, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels like there are lots of redundant code here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. removed.
network/message.go
Outdated
return mc, nil | ||
} | ||
|
||
func GetAdminClient(opts *config.Opts) *admin.Client { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there function ever called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Let me remove it.
network/message.go
Outdated
|
||
var onMessage *nkn.OnMessage | ||
for i := 0; i < 3; i++ { | ||
onMessage, err = mc.Send(nkn.NewStringArray(address), reqBytes, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onMessage -> onReply
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
NodeInfo []*nodeInfo `json:"nodeInfo"` | ||
} | ||
|
||
func SendMsg(mc *admin.Client, address string, msg interface{}, waitResponse bool) (*managerToMember, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Codes in this function seem to be mostly duplicated (admin/client.go:RPCCall())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
network/manager.go
Outdated
if err := m.saveNetworkData(); err != nil { | ||
return nil, err | ||
} | ||
noti := &managerToMember{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does noti
stands for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, it is an abbreviation for notification
, the message initiated from manager to member is set as notification.
I have modified all noti
to notification
for better readability.
network/manager.go
Outdated
return nil | ||
} | ||
|
||
func (m *Manager) UpdateName(address, name string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should manager also send message to members on update event? (update name, update ip, etc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I added two multicase functions to notify related members.
network/manager.go
Outdated
|
||
for _, n := range m.networkData.Member { | ||
acceptAddresses := m.networkData.AcceptAddress[n.Address] | ||
if len(acceptAddresses) > 0 && acceptAddresses[0] == AcceptAll { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anything other than acceptall we should handle?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The manager can set each member's accept nodes. One option is to accept all other members AcceptAll
. other options the manager set only some nodes which can accept the designated node.
network/manager.go
Outdated
|
||
networkDataFile = "network.json" | ||
|
||
AcceptAll = "all" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest we use AllMembers = "allMembers"
. There might be case when we have public nodes that accept connections from everyone (even not a member).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
network/manager.go
Outdated
return errNameExist | ||
} | ||
|
||
var ok1, ok2 bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok1 is defined twice.
Also I would recommend using isMember
and isWaiting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, modified.
ea3932e
to
07a0f9c
Compare
8e4b31f
to
779a4a9
Compare
b329261
to
579e873
Compare
61ead41
to
bb677e4
Compare
Signed-off-by: bill fort <[email protected]>
Manager
is a new node role of nConnect, which is the administrator node of the network;Member
node can join thisManager
's network;Manager
authorize a member'sJoinNetwork
request, the member can communicate with other nodes according to theManager
access setting.