Giter Site home page Giter Site logo

perlin-network / noise Goto Github PK

View Code? Open in Web Editor NEW
1.8K 1.8K 210.0 1.99 MB

A decentralized P2P networking stack written in Go.

Home Page: https://godoc.org/github.com/perlin-network/noise

License: MIT License

Go 99.89% Makefile 0.11%
cryptography golang network p2p peer-discovery

noise's People

Contributors

abbychau avatar cristaloleg avatar doug-perlin avatar ggoranov avatar itsalexyue avatar iwasaki-kenta avatar jack0 avatar losfair avatar muesli avatar target111 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

noise's Issues

NAT issues running noise in Docker containers

If you run two Docker containers with internal ports set at 3000 exposed to the host on a different port and attempt to connect them together you get the following error.

I0810 10:10:30.231989       1 plugin.go:32] Setting up NAT traversal for address: tcp://0.0.0.0:3000
W0810 10:10:40.233060       1 plugin.go:43] Unable to discover gateway: no NAT found
I0810 10:10:40.233504       1 network.go:205] Listening for peers on tcp://0.0.0.0:3000.
E0810 10:10:49.348053       1 network.go:407] network: peer should not dial itself

Plugin system for Network.

Right now there is unnecessary construction of a Kademlia DHT despite users not necessarily needing peer discovery.

We should abstract features such as message signing/peer discovery into Plugins instead.

  • Plugins can choose to bootstrap multiple MessageProcessors to a Network.
  • Plugins are specified through builder.NetworkBuilder.
  • Plugins can execute functions upon the receiving/sending of a message (for peer discovery, one can update the routing table everytime one receives a message from a specific peer).
  • Plugins can intercept and modify sent/received messages (messages can optionally be chosen to be signed or not).
  • Plugins can keep state (we can migrate out network.Routes to the plugin.)
  • Plugin state can be accessed from network through a concurrent-safe map.

Abstract away message handling.

We should give the choice of choosing to include in peer discovery as an option to developers, as it is currently baked in forcibly in PeerClient.

To do so, we need to package it with an type MessageHandler interface or type MessageProcessor interface and allow users to attach new message handlers/processors to a *Network.

From type PeerClient struct there is a reference to server *Server which can access network *Network so that we can get a reference list of all registered message handlers/processors to the *Network.

From a performance optimization perspective, we shouldn't naively loop through all registered message handlers and apply them to incoming messages from the network though.

Most probably, upon registration of a message handler/processor users should designate somehow (perhaps through a go bind on the struct implementing the MessageHandler/MessageProcessor interface?) what sort of messages are handled by a specific registered handler/processor, such that we can add it to a map of a list of processors that would then handle said message.

error: undefined: proto.InternalMessageInfo

examples/chat/messages/chat.pb.go:63:33: undefined: proto.InternalMessageInfo
protobuf/stream.pb.go:67:24: undefined: proto.InternalMessageInfo
protobuf/stream.pb.go:127:29: undefined: proto.InternalMessageInfo
protobuf/stream.pb.go:199:26: undefined: proto.InternalMessageInfo
protobuf/stream.pb.go:236:26: undefined: proto.InternalMessageInfo
protobuf/stream.pb.go:274:39: undefined: proto.InternalMessageInfo
protobuf/stream.pb.go:319:40: undefined: proto.InternalMessageInfo
protobuf/stream.pb.go:364:27: undefined: proto.InternalMessageInfo

protoc --version
libprotoc 3.6.0

Unable to build on Windows10

Due to this error I'm unable to build the project and test it using Windows10. Maybe is a good idea indicate it on readme?

Result of execute command vgo mod -vendor:

Javi@FOOOCK D:\Projects\go\src\github.com\perlin-network\noise (master)
> vgo generate ./...
go: extracting github.com/xtaci/kcp-go v0.0.0-20180203133237-42bc1dfefff5
-> unzip D:\Projects\go\src\mod\cache\download\github.com\xtaci\kcp-go\@v\v0.0.0-20180203133237-42bc1dfefff5.zip: invalid file name github.com/xtaci/[email protected]/.gitignore
go: extracting github.com/pkg/errors v0.8.0
-> unzip D:\Projects\go\src\mod\cache\download\github.com\pkg\errors\@v\v0.8.0.zip: invalid file name github.com/pkg/[email protected]/.gitignore
go: extracting github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
-> unzip D:\Projects\go\src\mod\cache\download\github.com\golang\glog\@v\v0.0.0-20160126235308-23def4e6c14b.zip: invalid file name github.com/golang/[email protected]/LICENSE
go: extracting github.com/gogo/protobuf v1.0.0
-> unzip D:\Projects\go\src\mod\cache\download\github.com\gogo\protobuf\@v\v1.0.0.zip: invalid file name github.com/gogo/[email protected]/.gitignore
go: extracting golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8
-> unzip D:\Projects\go\src\mod\cache\download\golang.org\x\crypto\@v\v0.0.0-20180621125126-a49355c7e3f8.zip: invalid file name golang.org/x/[email protected]/.gitattributes
go: extracting github.com/xtaci/smux v1.0.7
-> unzip D:\Projects\go\src\mod\cache\download\github.com\xtaci\smux\@v\v1.0.7.zip: invalid file name github.com/xtaci/[email protected]/.gitignore
go: extracting github.com/fd/go-nat v1.0.0
-> unzip D:\Projects\go\src\mod\cache\download\github.com\fd\go-nat\@v\v1.0.0.zip: invalid file name github.com/fd/[email protected]/LICENSE
go: import "github.com/perlin-network/noise/crypto/hashing/blake2b" ->
        import "golang.org/x/crypto/blake2b": unzip D:\Projects\go\src\mod\cache\download\golang.org\x\crypto\@v\v0.0.0-20180621125126-a49355c7e3f8.zip: invalid file name golang.org/x/[email protected]/.gitattributes
go: import "github.com/perlin-network/noise/crypto/signing/ed25519" ->
        import "golang.org/x/crypto/ed25519": unzip D:\Projects\go\src\mod\cache\download\golang.org\x\crypto\@v\v0.0.0-20180621125126-a49355c7e3f8.zip: invalid file name golang.org/x/[email protected]/.gitattributes
go: import "github.com/perlin-network/noise/examples/basic/messages" ->
        import "github.com/gogo/protobuf/gogoproto": unzip D:\Projects\go\src\mod\cache\download\github.com\gogo\protobuf\@v\v1.0.0.zip: invalid file name github.com/gogo/[email protected]/.gitignore
go: import "github.com/perlin-network/noise/examples/basic/messages" ->
        import "github.com/gogo/protobuf/proto": unzip D:\Projects\go\src\mod\cache\download\github.com\gogo\protobuf\@v\v1.0.0.zip: invalid file name github.com/gogo/[email protected]/.gitignore
go: import "github.com/perlin-network/noise/examples/chat" ->
        import "github.com/golang/glog": unzip D:\Projects\go\src\mod\cache\download\github.com\golang\glog\@v\v0.0.0-20160126235308-23def4e6c14b.zip: invalid file name github.com/golang/[email protected]/LICENSE
go: import "github.com/perlin-network/noise/examples/stream" ->
        import "github.com/xtaci/smux": unzip D:\Projects\go\src\mod\cache\download\github.com\xtaci\smux\@v\v1.0.7.zip: invalid file name github.com/xtaci/[email protected]/.gitignore
go: import "github.com/perlin-network/noise/network" ->
        import "github.com/gogo/protobuf/types": unzip D:\Projects\go\src\mod\cache\download\github.com\gogo\protobuf\@v\v1.0.0.zip: invalid file name github.com/gogo/[email protected]/.gitignore
go: import "github.com/perlin-network/noise/network" ->
        import "github.com/pkg/errors": unzip D:\Projects\go\src\mod\cache\download\github.com\pkg\errors\@v\v0.8.0.zip: invalid file name github.com/pkg/[email protected]/.gitignore
go: import "github.com/perlin-network/noise/network" ->
        import "github.com/xtaci/kcp-go": unzip D:\Projects\go\src\mod\cache\download\github.com\xtaci\kcp-go\@v\v0.0.0-20180203133237-42bc1dfefff5.zip: invalid file name github.com/xtaci/[email protected]/.gitignore
go: import "github.com/perlin-network/noise/network/nat" ->
        import "github.com/fd/go-nat": unzip D:\Projects\go\src\mod\cache\download\github.com\fd\go-nat\@v\v1.0.0.zip: invalid file name github.com/fd/[email protected]/LICENSE

chat.gif is outdated

chat.gif is outdated since "-peers localhost:3000" is not working without protocol specification

kcp protocol error on examples/chat

when I blank protocol is fine, when use protocol=kcp, error reported:
xxxx$ go run main.go -host=192.168.1.102 -peers=kcp://192.168.1.104:3000 -protocol=kcp
2018-10-20T18:28:21+08:00 |WARN| caller=/Users/xxxx/go/src/github.com/perlin-network/noise/network/network.go:116 error="broken pipe"

one more thing, under macos and win10,client on win10 exit; under macOS and ubuntu, it goes well.

Fix receive window.

Say we receive messages with nonce 1, 2, 3 and 5. Calling Update() will process messages 1, 2, 3.

Calling Update() once message 4 comes in will process messages 4 and 5.

Receive window is used for buffering messages that are out of order.

Chat client crashes when a message is sent:

So, in one window I have a cloud machine open, which is running like this:

root@testnet2:~/go/bin# ./chat -host 149.28.45.92
I0713 21:07:49.195013   19634 main.go:45] Private Key: 537d7e7c0e196c1ad8b7afe172db0739e978665db78797305a30b7ed57e0602779f64ca55b2a9cc8ceffa4db958b8c9439049ebd4dcbd5e544f255c054a88b52
I0713 21:07:49.195447   19634 main.go:46] Public Key: 79f64ca55b2a9cc8ceffa4db958b8c9439049ebd4dcbd5e544f255c054a88b52
I0713 21:07:49.196079   19634 network.go:215] Listening for peers on tcp://149.28.45.92:3000.
E0713 21:08:28.989027   19634 network.go:411] dial tcp 98.118.185.162:26110: connect: connection refused
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x5d9ade]

goroutine 19 [running]:
github.com/perlin-network/noise/network.(*Network).Accept.func2(0xc420084180, 0xc42008a0a0, 0xc42001c460, 0xc42000e088, 0xc42000e080, 0xc42000c3c0, 0xc42000e078)
        /root/go/src/github.com/perlin-network/noise/network/network.go:433 +0x15e
created by github.com/perlin-network/noise/network.(*Network).Accept
        /root/go/src/github.com/perlin-network/noise/network/network.go:394 +0x333
root@testnet2:~/go/bin# 

In my IDE, where I've modified "chat" to use NAT and connect to the cloud instance of chat, I have this going on:

admins-MacBook-Pro:chat admin$ ./chat -peers tcp://149.28.45.92:3000
I0713 17:08:26.661685   10198 main.go:46] Private Key: c3e6c04553b19f9d44057a06dd884429183a20a3b11c4b2fc3138ad8a3bbf32fb6848b3ec12e9ca2259ee98f6442a2b6d402e7897938ef32c337606518c9a712
I0713 17:08:26.661753   10198 main.go:47] Public Key: b6848b3ec12e9ca2259ee98f6442a2b6d402e7897938ef32c337606518c9a712
I0713 17:08:26.663017   10198 plugin.go:25] Setting up NAT traversal...
I0713 17:08:28.786533   10198 plugin.go:52] Discovered gateway following the protocol UPNP (IG1-IP1).
I0713 17:08:28.786559   10198 plugin.go:54] Internal IP: 192.168.1.166
I0713 17:08:28.786571   10198 plugin.go:55] External IP: 98.118.185.162
I0713 17:08:28.941708   10198 plugin.go:64] External port 26110 now forwards to your local port 3000.
I0713 17:08:28.941745   10198 plugin.go:75] Other peers may connect to you through the address tcp://98.118.185.162:26110.
I0713 17:08:28.942029   10198 network.go:215] Listening for peers on tcp://98.118.185.162:26110.
hi
I0713 17:08:32.445675   10198 main.go:82] <tcp://98.118.185.162:26110> hi

When I send "hi" to the cloud instance from my mac, the cloud instance crashes and burns.

LRU cache error and potential improvements.

When I was making a test on lru/cache, on inserting excessive items to lru/cache, item := c.order.Remove(c.order.Back()).(*cacheItem) will cause problem due to:

panic: interface conversion: interface {} is string, not *lru.cacheItem

as c.order is only built up by value, so there is no way to get back key from it.

Also, we don't have to evict items before checking if cache key is hit.

Intermittent Crash (at startup) in Chat App

So... a little bit of background-- I first saw this issue after building the chat example multiplatform using Gox after I put the app on a raspberry Pi of mine. Since then, I've seen it on my mac as well.

I can't quite make heads or tails of it (I've tried) so I'm filing this issue. I'm in the discord if you've any questions.

./chat
./chat flag redefined: log_dir
panic: ./chat flag redefined: log_dir

goroutine 1 [running]:
flag.(*FlagSet).Var(0xc420074060, 0x1292b40, 0xc4200107e0, 0x1269f85, 0x7, 0x12756a5, 0x2f)
	/usr/local/Cellar/go/1.10/libexec/src/flag/flag.go:810 +0x540
flag.(*FlagSet).StringVar(0xc420074060, 0xc4200107e0, 0x1269f85, 0x7, 0x0, 0x0, 0x12756a5, 0x2f)
	/usr/local/Cellar/go/1.10/libexec/src/flag/flag.go:713 +0x8b
flag.(*FlagSet).String(0xc420074060, 0x1269f85, 0x7, 0x0, 0x0, 0x12756a5, 0x2f, 0xc4200107d0)
	/usr/local/Cellar/go/1.10/libexec/src/flag/flag.go:726 +0x8b
flag.String(0x1269f85, 0x7, 0x0, 0x0, 0x12756a5, 0x2f, 0x11b3a87)
	/usr/local/Cellar/go/1.10/libexec/src/flag/flag.go:733 +0x69

use UPNP

log:
I0910 11:42:08.731264 15248 main1.go:46] Private Key: 79f92dfe6267bcc95d347a0447408bf57c14fb8781e223e273afedbe5248dd12c3206ae6362428246fea928366b993f66d5ce0d938c50a2b36cb91be280cf148
I0910 11:42:08.738208 15248 main1.go:47] Public Key: c3206ae6362428246fea928366b993f66d5ce0d938c50a2b36cb91be280cf148
I0910 11:42:08.741184 15248 plugin.go:32] Setting up NAT traversal for address: kcp://127.0.0.1:3002
I0910 11:42:10.946909 15248 plugin.go:59] Discovered gateway following the protocol UPNP (IG1-IP1).
I0910 11:42:10.946909 15248 plugin.go:61] Internal IP: 192.168.2.102
I0910 11:42:10.946909 15248 plugin.go:62] External IP: 100.100.149.137
I0910 11:42:11.093523 15248 plugin.go:71] External port 60858 now forwards to your local port 3002.
I0910 11:42:11.093523 15248 plugin.go:82] Other peers may connect to you through the address kcp://100.100.149.137:60858.
I0910 11:42:11.094019 15248 network.go:206] Listening for peers on kcp://100.100.149.137:60858.

Why the External IP is not my public network IP?

`sync.Once` for replies to a received request.

We should enforce somehow that requests received should only be replied to once. sync.Once may be an option.

Additionally, we should make it possible to not have to provide the request nonce to client.Reply(request nonce, message) with an example case of its usage in network/discovery/incoming.go.

We can cache the request nonce somehow specifically to a given processed IncomingMessage.

If the current incoming message is not a request/reply RPC, client.Reply() will error.

Incorrect peer.ID sent when using NAT traversal.

Upon enabling the NAT traversal plugin, one's peer.ID gets set to their external WAN IP.

This prevents users from spawning up local peer nodes and having them formate a cluster with one another, and only allows for peers coming from an external network.

This is because the peer.ID that gets distributed out contains the users external WAN IP, which is not directly connectable to from peers in a local network. Hence, peer discovery will fail locally.

Best solution for now is to check if a nodes own peer.ID address is equivalent to a peer that is being dialed peer.ID address, and to automatically default it to dialing the loopback address 127.0.0.1.

kcp error on examples/chat

when I blank protocol it's fine, when use protocol=kcp, error reported:
xxxx$ go run main.go -host=192.168.1.102 -peers=kcp://192.168.1.104:3000 -protocol=kcp
2018-10-20T18:28:21+08:00 |WARN| caller=/Users/xxxx/go/src/github.com/perlin-network/noise/network/network.go:116 error="broken pipe"

one more thing, when peer on win10, it exit; ok under macOS and ubuntu

Exactly-once message propagation.

Not mandatory for release.

Syntax:

  • 0<2 implies that Node 2 bootstrapped with Node 0.
  • 0<=2 implies that Node 2 sent a message to Node 0.

Say we have a setup 0<1 + 1<2. Proxying means: 0=>1 + 1=>2. Node 0 sends a message to Node 1 who notices the request to have the message proxied/propagated to Node 2.

To do this, some requirements need to be done:

  • If we have 1000 nodes, we don't want to redundantly keep having nodes proxy a single particular message multiple times. To do this, our message keeps track of nodes that have already been proxied through via. a space-efficient data structure (Bloom/Cuckoo Filter).
  • We have a routing table from Kademlia. We can use this to our advantage, as XOR'ing the proxy target node ID with our own node ID will give us the bucket ID filled with nodes most likely closest to the target node. Hence, if the target node is not in our list of nodes, we broadcast and have the closest nodes proxy the message forward. If the target node is in our list of nodes, just send the message directly to it.

Peer broadcasting methods.

Add in methods to choose how to broadcast messages to select peers.

  • Randomly sample K peers from the population.
  • Broadcast to all peers.
  • Broadcast to a given group of peers by address/peer ID.

Cleanup documentation

Clean-up documentation and code and create usage examples for Go developers.

  • readme
  • license

Connect Bug

I did an experiment:
1:I ran chat/main.go on the public network.
2:I also ran chat/main.go on my local intranet.

The intranet takes the initiative to connect to the public network.
and connect failure

log:
1:public network:
I0914 15:35:59.067335 5092 main.go:45] Private Key: e1c79968020ee18a725849826e7130c4bb9e4962d255b6829fd8ab64534658f85640464458ddeef9eeb93368779c7015a2a43ff374ff23b3eae23b47dbfb75e8
I0914 15:35:59.067392 5092 main.go:46] Public Key: 5640464458ddeef9eeb93368779c7015a2a43ff374ff23b3eae23b47dbfb75e8
I0914 15:35:59.067700 5092 network.go:206] Listening for peers on tcp://47.91.166.18:3001.
E0914 15:38:06.366141 5092 network.go:319] dial tcp 183.192.11.228:3000: connect: connection timed out

2:local intranet:
I0914 15:36:05.452905 21932 main.go:46] Private Key: 31d4fefef611b233374a1b99363eb55dd0919b383108911bc909f455de22af0d425efc07c0d7d68d203d0e3ea1c8702a2968dd3d16f34a3909648520ade5c91d
I0914 15:36:05.459852 21932 main.go:47] Public Key: 425efc07c0d7d68d203d0e3ea1c8702a2968dd3d16f34a3909648520ade5c91d
I0914 15:36:05.464287 21932 network.go:206] Listening for peers on tcp://127.0.0.1:3000.

I think the port of public network connect local intranet should‘t be 3000 ,is right?

forgive my poor English

Make protocol pluggable.

It would be great to be able to make the underlying protocol pluggable.
This way plugging in a tor layer can give you anonymous peers.

possible to use when a member cannot be dialed?

Hi!

I'm trying to determine if Noise can be used when a member of the p2p network cannot be dialed. I was experimenting using docker where host B can dial host A, but host A cannot dial host B.

I tried to have host B bootstrap to A, but then it appears that A tries to dial B and it fails... it doesn't look like a bi-directional connection is setup.

Is that true?

My use-case is for clients to connect to the network where the built-in NAT busting doesn't work, but we could establish relays (similar to your proxy example) to get messages to the clients.

Motivation

What exactly is the motivation? After all, TCP itself is decentralized and robust. Cryptography is an addon and HTTP/2 already supports it.

Is there a read up somewhere on the reasoning and the potential applications?

Why do you use UPnP nat traversal instead of ICE (STUN, TURN, UDP hole punching)?

Hello.

I am looking for solution for 2P2 file sharing. Your library looks good, but it seems, that there is a problem with nat traversal. You use UPnP nat traversal. But, what if client router does not support it?

I would be happy to know, why you decide to use UPnP nat traversal instead of ICE? Can you explain, please?

Setup Issues

I am running into a vgo mod -sync error, that tells me it cannot find:

go: import "github.com/gogo/protobuf/protoc-gen-gogofaster/gocode/src/github.com/golang/mock/mockgen/tests/vendor_dep" ->
import "a": cannot find module providing package a

I had an issue with protobufs 3.6 not working and versioned down to 3.5.1, that fixed the protobuf issue so maybe there are other versioning issues?

running ubuntu 18.04

Cleanup Stream API.

  • 1. Replace Address string in *Network and *PeerClient with AddressInfo.
  • 2. Merge AddressInfo with NoiseAddr in *PeerClient.
  • 3. Implement read/write deadlines and all of net.Conn interface for *PeerClient.
  • 4. Rename StreamPacket to Bytes.
  • 5. Add exit signal (go channel) for client to stop connections and everything.
  • 6. Add exit signal (go channel) for network to stop connections, workers and everything.

Remotely crash a peer by binding to 0.0.0.0

If the local peer binds to 0.0.0.0 with the code

builder.SetAddress(network.FormatAddress(
	"kcp",
	"0.0.0.0",
	7946))

and a message is sent to the remote (in my case the initial state sync), the remote peer will try to dial itself and panic with the error:

E1001 14:12:43.652615    6010 network.go:397] network: peer should not dial itself
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0xa6fecd]

goroutine 48 [running]:
github.com/gladiusio/gladius-controld/vendor/github.com/perlin-network/noise/network.(*Network).Accept.func2(0xc0003ba840, 0xc0002d1ee0, 0xc000350c80, 0xc00000e170, 0xc0003b87f0, 0xc0003b87d0, 0xc0003b51a0)
        /home/alex/go/src/github.com/gladiusio/gladius-controld/vendor/github.com/perlin-network/noise/network/network.go:402 +0xed
created by github.com/gladiusio/gladius-controld/vendor/github.com/perlin-network/noise/network.(*Network).Accept
        /home/alex/go/src/github.com/gladiusio/gladius-controld/vendor/github.com/perlin-network/noise/network/network.go:375 +0x1cf

Create proxying example.

Of course, the main goal is to make examples as intuitive as possible. We should all try out different examples to illustrate that it's relatively easy to use Noise with a minimal number of LoC.

This example constitutes of proxying messages from one node to another.

Steps

  1. We have Node 0, 1, 2.
  2. Nodes 1, 2 will bootstrap with Node 0.
  3. Node 0 will send a message to Node 1.
  4. Node 1 will proxy the message to Node 2.
  5. Node 2 will print out that they received the message.

Style Reference

Please refer to the comment styling and example directory format for the basic example located here: https://github.com/perlin-network/noise/tree/master/examples/basic

Create request builder.

Initiating a request to a peer should be configurable with many options.

We can utilize the same builder pattern we see in building new peer networks to create requests with specific options.

Example usage:

request := &builders.RequestBuilder{}
request.SetTimeout(3 * time.Second)
request.SetMessage(message proto.Message)

...

client.Request(request.BuildRequest())

Crash when incoming message has nil field "Sender"

I've been having random crashes with a peer (sometimes connected to other peers, and sometimes on it's own) with the error:

2018/09/19 16:45:50
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0xa3815d]

goroutine 49 [running]:
github.com/gladiusio/gladius-node/vendor/github.com/perlin-network/noise/network.(*Network).Accept.func2(0xc4203aba60, 0xc420312d00, 0xc42006c380, 0xc42000f220, 0xc4203ad6b0, 0xc4203ad690, 0xc4203df890)
        /ext-go/1/src/github.com/gladiusio/gladius-node/vendor/github.com/perlin-network/noise/network/network.go:402 +0xed
created by github.com/gladiusio/gladius-node/vendor/github.com/perlin-network/noise/network.(*Network).Accept
        /ext-go/1/src/github.com/gladiusio/gladius-node/vendor/github.com/perlin-network/noise/network/network.go:375 +0x1d4

The random nature of this, and the fact it happens when there are no peers connected makes me think it's this section of our code:

func (state *StatePlugin) Startup(net *network.Network) {
	// TODO: Find out why this crashes the network on ocassion
	 go func() {
		time.Sleep(60 * time.Second)
	 	net.BroadcastRandomly(&messages.SyncRequest{}, 1)
	 }()
}

It looks like this if statement is the problem at network.go:402, dereferencing msg.Sender causes a panic.

// Peer sent message with a completely different ID. Disconnect.
if !client.ID.Equals(peer.ID(*msg.Sender)) {
	glog.Errorf("message signed by peer %s but client is %s", peer.ID(*msg.Sender), client.ID.Address)
	return
}

I also get an error about the peer should not dial itself even if I haven't explicitly called p.net.Bootstrap(addressList...) so I believe that the above code is broadcasting before the network has been bootstrapped, and that the BroadcastRandomly method seems to be able to dial itself. This is running on a VPS and listening on it's public IP with the code:

// Use KCP instead of TCP, and config bind address and bind port
builder.SetAddress(network.FormatAddress(
	"kcp",
	viper.GetString("P2P.BindAddress"),
	uint16(viper.GetInt("P2P.BindPort")))

// This is our network state object
s := state.New()
s.RegisterNodeSingleFields("ip_address", "content_port", "heartbeat")
s.RegisterNodeListFields("disk_content")

s.RegisterPoolListFields("required_content")

// Register peer discovery plugin.
// TODO: Setup an authorized DHT plugin
builder.AddPlugin(new(discovery.Plugin))

// Add the exponential backoff plugin
builder.AddPlugin(new(backoff.Plugin))

// Create our state sync plugin
statePlugin := new(StatePlugin)
statePlugin.peerState = s
builder.AddPlugin(statePlugin)

net, err := builder.Build()
if err != nil {
	log.Fatal(err)
	return nil
}

go net.Listen()

I haven't tested with TCP instead of KCP though.

How to use backoff plugin?

I add AddPlugin(new(backoff.Plugin)) in chat example, and disconnect main node ,and restart it
but client cant reconnect main node, do i have to config some backoff parameters? can you give some demo to show backoff reconnect case? thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.