-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
122 lines (104 loc) · 3.53 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
package main
import (
"fmt"
"github.com/pion/stun"
"github.com/pion/turn/v2"
"log"
"net"
"os"
"os/signal"
"regexp"
"syscall"
)
// stunLogger wraps a PacketConn and prints incoming/outgoing STUN packets
// This pattern could be used to capture/inspect/modify data as well
type stunLogger struct {
net.PacketConn
}
func (s *stunLogger) WriteTo(p []byte, addr net.Addr) (n int, err error) {
if n, err = s.PacketConn.WriteTo(p, addr); err == nil && stun.IsMessage(p) {
msg := &stun.Message{Raw: p}
if err = msg.Decode(); err != nil {
return
}
fmt.Printf("Outbound STUN: %s \n", msg.String())
}
return
}
func (s *stunLogger) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
if n, addr, err = s.PacketConn.ReadFrom(p); err == nil && stun.IsMessage(p) {
msg := &stun.Message{Raw: p}
if err = msg.Decode(); err != nil {
return
}
fmt.Printf("Inbound STUN: %s \n", msg.String())
}
return
}
func main() {
publicIP := os.Getenv("KERBEROS_TURN_PUBLIC_IP") //"192.168.86.175"
users := os.Getenv("KERBEROS_TURN_USERS") //"username1=password1"
port := os.Getenv("KERBEROS_TURN_PORT") //"443"
realm := os.Getenv("KERBEROS_TURN_REALM") //"kerberos.io"
if publicIP == "" {
log.Fatalf("'public-ip' is required")
} else if users == "" {
log.Fatalf("'users' is required")
}
// Create a TCP listener to pass into pion/turn
// pion/turn itself doesn't allocate any TCP listeners, but lets the user pass them in
// this allows us to add logging, storage or modify inbound/outbound traffic
tcpListener, err := net.Listen("tcp4", "0.0.0.0:"+port)
if err != nil {
log.Panicf("Failed to create TURN server listener: %s", err)
}
// Or if you want toCreate a UDP listener to pass into pion/turn
// pion/turn itself doesn't allocate any UDP sockets, but lets the user pass them in
// this allows us to add logging, storage or modify inbound/outbound traffic
// --- (UNCOMMENT BELOW) ---
// udpListener, err := net.ListenPacket("udp4", "0.0.0.0:"+strconv.Itoa(*port))
// if err != nil {
// log.Panicf("Failed to create TURN server listener: %s", err)
// }
// Cache -users flag for easy lookup later
// If passwords are stored they should be saved to your DB hashed using turn.GenerateAuthKey
usersMap := map[string][]byte{}
for _, kv := range regexp.MustCompile(`(\w+)=(\w+)`).FindAllStringSubmatch(users, -1) {
usersMap[kv[1]] = turn.GenerateAuthKey(kv[1], realm, kv[2])
}
s, err := turn.NewServer(turn.ServerConfig{
Realm: realm,
// Set AuthHandler callback
// This is called everytime a user tries to authenticate with the TURN server
// Return the key for that user, or false when no user is found
AuthHandler: func(username string, realm string, srcAddr net.Addr) ([]byte, bool) {
if key, ok := usersMap[username]; ok {
return key, true
}
return nil, false
},
// ListenerConfig is a list of Listeners and the configuration around them
ListenerConfigs: []turn.ListenerConfig{
{
Listener: tcpListener,
RelayAddressGenerator: &turn.RelayAddressGeneratorStatic{
RelayAddress: net.ParseIP(publicIP),
Address: "0.0.0.0",
//MinPort: 50000, // If using UDP listener, you can specify the lower range of ports.
//MaxPort: 55000, // If using UDP listener, you can specify the upper range of ports.
},
},
},
})
if err != nil {
log.Panic(err)
}
fmt.Println("Starting TURN")
// Block until user sends SIGINT or SIGTERM
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
<-sigs
if err = s.Close(); err != nil {
log.Panic(err)
}
}