forked from perlin-network/noise
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
123 lines (97 loc) · 2.65 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main
import (
"bufio"
"flag"
"github.com/Yayg/noise"
"github.com/Yayg/noise/cipher/aead"
"github.com/Yayg/noise/handshake/ecdh"
"github.com/Yayg/noise/log"
"github.com/Yayg/noise/payload"
"github.com/Yayg/noise/protocol"
"github.com/Yayg/noise/skademlia"
"github.com/pkg/errors"
"os"
"strconv"
"strings"
)
/** DEFINE MESSAGES **/
var (
opcodeChat noise.Opcode
_ noise.Message = (*chatMessage)(nil)
)
type chatMessage struct {
text string
}
func (chatMessage) Read(reader payload.Reader) (noise.Message, error) {
text, err := reader.ReadString()
if err != nil {
return nil, errors.Wrap(err, "failed to read chat msg")
}
return chatMessage{text: text}, nil
}
func (m chatMessage) Write() []byte {
return payload.NewWriter(nil).WriteString(m.text).Bytes()
}
/** ENTRY POINT **/
func setup(node *noise.Node) {
opcodeChat = noise.RegisterMessage(noise.NextAvailableOpcode(), (*chatMessage)(nil))
node.OnPeerInit(func(node *noise.Node, peer *noise.Peer) error {
peer.OnConnError(func(node *noise.Node, peer *noise.Peer, err error) error {
log.Info().Msgf("Got an error: %v", err)
return nil
})
peer.OnDisconnect(func(node *noise.Node, peer *noise.Peer) error {
log.Info().Msgf("Peer %v has disconnected.", peer.RemoteIP().String()+":"+strconv.Itoa(int(peer.RemotePort())))
return nil
})
go func() {
for {
msg := <-peer.Receive(opcodeChat)
log.Info().Msgf("[%s]: %s", protocol.PeerID(peer), msg.(chatMessage).text)
}
}()
return nil
})
}
func main() {
hostFlag := flag.String("h", "127.0.0.1", "host to listen for peers on")
portFlag := flag.Uint("p", 3000, "port to listen for peers on")
flag.Parse()
params := noise.DefaultParams()
//params.NAT = nat.NewPMP()
params.Keys = skademlia.RandomKeys()
params.Host = *hostFlag
params.Port = uint16(*portFlag)
node, err := noise.NewNode(params)
if err != nil {
panic(err)
}
defer node.Kill()
p := protocol.New()
p.Register(ecdh.New())
p.Register(aead.New())
p.Register(skademlia.New())
p.Enforce(node)
setup(node)
go node.Listen()
log.Info().Msgf("Listening for peers on port %d.", node.ExternalPort())
if len(flag.Args()) > 0 {
for _, address := range flag.Args() {
peer, err := node.Dial(address)
if err != nil {
panic(err)
}
skademlia.WaitUntilAuthenticated(peer)
}
peers := skademlia.FindNode(node, protocol.NodeID(node).(skademlia.ID), skademlia.BucketSize(), 8)
log.Info().Msgf("Bootstrapped with peers: %+v", peers)
}
reader := bufio.NewReader(os.Stdin)
for {
txt, err := reader.ReadString('\n')
if err != nil {
panic(err)
}
skademlia.BroadcastAsync(node, chatMessage{text: strings.TrimSpace(txt)})
}
}