1package main 2 3import ( 4 "flag" 5 "log" 6 "net" 7 "os" 8 "os/signal" 9 "strconv" 10 "syscall" 11 12 "github.com/pion/logging" 13 "github.com/pion/turn/v2" 14) 15 16func main() { 17 publicIP := flag.String("public-ip", "", "IP Address that TURN can be contacted by.") 18 port := flag.Int("port", 3478, "Listening port.") 19 authSecret := flag.String("authSecret", "", "Shared secret for the Long Term Credential Mechanism") 20 realm := flag.String("realm", "pion.ly", "Realm (defaults to \"pion.ly\")") 21 flag.Parse() 22 23 if len(*publicIP) == 0 { 24 log.Fatalf("'public-ip' is required") 25 } else if len(*authSecret) == 0 { 26 log.Fatalf("'authSecret' is required") 27 } 28 29 // Create a UDP listener to pass into pion/turn 30 // pion/turn itself doesn't allocate any UDP sockets, but lets the user pass them in 31 // this allows us to add logging, storage or modify inbound/outbound traffic 32 udpListener, err := net.ListenPacket("udp4", "0.0.0.0:"+strconv.Itoa(*port)) 33 if err != nil { 34 log.Panicf("Failed to create TURN server listener: %s", err) 35 } 36 37 // NewLongTermAuthHandler takes a pion.LeveledLogger. This allows you to intercept messages 38 // and process them yourself. 39 logger := logging.NewDefaultLeveledLoggerForScope("lt-creds", logging.LogLevelTrace, os.Stdout) 40 41 s, err := turn.NewServer(turn.ServerConfig{ 42 Realm: *realm, 43 // Set AuthHandler callback 44 // This is called everytime a user tries to authenticate with the TURN server 45 // Return the key for that user, or false when no user is found 46 AuthHandler: turn.NewLongTermAuthHandler(*authSecret, logger), 47 // PacketConnConfigs is a list of UDP Listeners and the configuration around them 48 PacketConnConfigs: []turn.PacketConnConfig{ 49 { 50 PacketConn: udpListener, 51 RelayAddressGenerator: &turn.RelayAddressGeneratorStatic{ 52 RelayAddress: net.ParseIP(*publicIP), // Claim that we are listening on IP passed by user (This should be your Public IP) 53 Address: "0.0.0.0", // But actually be listening on every interface 54 }, 55 }, 56 }, 57 }) 58 if err != nil { 59 log.Panic(err) 60 } 61 62 // Block until user sends SIGINT or SIGTERM 63 sigs := make(chan os.Signal, 1) 64 signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) 65 <-sigs 66 67 if err = s.Close(); err != nil { 68 log.Panic(err) 69 } 70} 71