-
Notifications
You must be signed in to change notification settings - Fork 26
/
handlers.go
121 lines (103 loc) · 2.97 KB
/
handlers.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
package main
import (
"encoding/base64"
"errors"
"fmt"
"log"
"strconv"
"strings"
"github.com/mitchellh/mapstructure"
"github.com/wilfreddenton/crypto"
"github.com/wilfreddenton/udp-hole-punching/shared"
)
func greetingHandler(conn shared.Conn, m *shared.Message) (*shared.Message, error) {
// ensure that public key was sent in greeting request
str, ok := m.Content.(string)
if !ok {
return nil, errors.New("greeting request must contain client's public key")
}
// get public key contained in content
bs, err := base64.StdEncoding.DecodeString(str)
if err != nil {
return nil, err
}
// create shared secret from private key and peer public key
var clientPubKey [32]byte
copy(clientPubKey[:], bs[:])
conn.SetSecret(crypto.GenSharedSecret(priKey, clientPubKey))
// send greeting response
return &shared.Message{
Type: "greeting",
Content: base64.StdEncoding.EncodeToString(pubKey[:]),
}, nil
}
// register the requesting peer in the server
func registerHandler(peers shared.Peers, c shared.Conn, m *shared.Message) (*shared.Message, error) {
// map -> structure the content
var registration shared.Registration
err := mapstructure.Decode(m.Content, ®istration)
if err != nil {
return nil, err
}
// register peer
endpoint := strings.Split(c.GetAddr().String(), ":")
if len(endpoint) != 2 {
return nil, errors.New("address is not valid")
}
port, err := strconv.Atoi(endpoint[1])
if err != nil {
return nil, err
}
peers[m.PeerID] = &shared.Peer{
ID: m.PeerID,
Username: registration.Username,
Endpoint: shared.Endpoint{
IP: endpoint[0],
Port: port,
},
}
log.Printf("Registered peer: %s at addr %s", m.PeerID, c.GetAddr().String())
// confirm registry to peer
return &shared.Message{
Type: "register",
Encrypt: true,
}, nil
}
// facilitate in the establishing of the p2p connection
func establishHandler(peers shared.Peers, conns shared.Conns, m *shared.Message) (*shared.Message, error) {
// make sure requesting peer has registered with server
rp, ok := peers[m.PeerID]
if !ok {
return nil, errors.New("client is not registered with this server")
}
// make sure that a valid payload was sent
id, ok := m.Content.(string)
if !ok {
return nil, errors.New("request content is malformed")
}
// make sure the other peer has registered with the server
op, ok := peers[id]
if !ok {
return nil, fmt.Errorf("The peer: %s has not registered with the server.", id)
}
// get conn for other peer
conn, ok := conns[op.Endpoint.String()]
if !ok {
return nil, fmt.Errorf("Could not resolve the peer: %s's conn", id)
}
// send requesting peer's endpoint to other peer
conn.Send(&shared.Message{
Type: "establish",
Content: rp,
Encrypt: true,
})
// send requesting peer other peer's endpoint
return &shared.Message{
Type: "establish",
Content: op,
Encrypt: true,
}, nil
}
func notFoundHandler(m *shared.Message) (*shared.Message, error) {
return nil, fmt.Errorf("Request type %s undefined", m.Type)
}