-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpasstor.go
113 lines (96 loc) · 2.56 KB
/
passtor.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
package passtor
import (
"fmt"
"log"
"net"
"os"
"sync"
"go.dedis.ch/protobuf"
)
// NewPasstor creates and return a new Passtor instance
func NewPasstor(name, addr string, verbose int) Passtor {
udpAddr, err := net.ResolveUDPAddr("udp4", addr)
checkErr(err)
pConn, err := net.ListenUDP("udp4", udpAddr)
checkErr(err)
tcpAddr, err := net.ResolveTCPAddr("tcp4", addr)
checkErr(err)
// create the passtor printers
printer := Printer{
Verbose: verbose,
Printer: log.New(os.Stdout, "", 0),
ErrPrinter: log.New(os.Stderr, "", 0),
}
// create the message counter used to associate reply with request
var counter uint64
c := MessageCounter{
IDCounter: &counter,
Mutex: &sync.Mutex{},
PendingMsg: make(map[uint64]*chan Message),
}
// create the passtor instance
p := Passtor{
Name: name,
Messages: &c,
PConn: pConn,
ClientAddr: tcpAddr,
Printer: printer,
Buckets: make(map[uint16]*Bucket),
Accounts: make(map[Hash]*AccountInfo),
}
// set the passtor identifier
p.SetIdentity()
// set self address
p.Addr = NodeAddr{Addr: *udpAddr, NodeID: p.NodeID}
// add self to routing table
p.AddPeerToBucket(p.Addr)
p.Printer.Print(fmt.Sprint("NodeID: ", p.NodeID), V3)
return p
}
// GetMessageID get the next message ID, ids starting at 1
func (c MessageCounter) GetMessageID() uint64 {
c.Mutex.Lock()
*c.IDCounter++
id := *c.IDCounter
c.Mutex.Unlock()
return id
}
// ListenToPasstors listen on the udp connection used to communicate with other
// passtors, and distribute received messages to HandleMessage()
func (p *Passtor) ListenToPasstors() {
buf := make([]byte, BUFFERSIZE)
for {
// read new message
m, _, err := p.PConn.ReadFromUDP(buf)
checkErr(err)
// copy the receive buffer to avoid that it is modified while being used
tmp := make([]byte, m)
copy(tmp, buf[:m])
go p.HandleMessage(tmp)
}
}
func (p *Passtor) ListenToClients() {
server, err := net.ListenTCP("tcp4", p.ClientAddr)
accounts := make(Accounts)
if err != nil {
fmt.Println("Error while starting TCP server")
return
}
defer server.Close()
for {
conn, _ := server.Accept()
packetBytes := make([]byte, TCPMAXPACKETSIZE)
_, err := conn.Read(packetBytes)
if err != nil {
println("Unable to read packet from TCP connection")
}
var message ClientMessage
protobuf.Decode(packetBytes, &message)
response := p.HandleClientMessage(accounts, message)
responseBytes, err := protobuf.Encode(response)
if err != nil {
fmt.Println("Error while parsing response to be sent to client")
}
conn.Write(responseBytes)
}
}