mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-12 08:45:38 +02:00
⭐ feat(relay): Port muxing and TLS (#197)
## Description This PR will work on adding port muxing (share single port for HTTP/WS + WebRTC connections), along with API communication. ## Type of Change - [x] Bug fix (non-breaking change) - [x] New feature (non-breaking change) ## Checklist - [ ] I have updated relevant documentation - [x] My code follows the project's coding style - [x] My changes generate no new warnings/errors --------- Co-authored-by: DatCaptainHorse <DatCaptainHorse@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
321dda60d9
commit
49853807a1
@@ -1,6 +1,7 @@
|
||||
package relay
|
||||
|
||||
import (
|
||||
"github.com/pion/ice/v4"
|
||||
"github.com/pion/interceptor"
|
||||
"github.com/pion/webrtc/v4"
|
||||
"log"
|
||||
@@ -38,7 +39,7 @@ func InitWebRTCAPI() error {
|
||||
PayloadType: 49,
|
||||
},
|
||||
} {
|
||||
if err := mediaEngine.RegisterCodec(codec, webrtc.RTPCodecTypeVideo); err != nil {
|
||||
if err = mediaEngine.RegisterCodec(codec, webrtc.RTPCodecTypeVideo); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -58,12 +59,28 @@ func InitWebRTCAPI() error {
|
||||
// New in v4, reduces CPU usage and latency when enabled
|
||||
settingEngine.EnableSCTPZeroChecksum(true)
|
||||
|
||||
// Set the UDP port range used by WebRTC
|
||||
err = settingEngine.SetEphemeralUDPPortRange(uint16(flags.WebRTCUDPStart), uint16(flags.WebRTCUDPEnd))
|
||||
if err != nil {
|
||||
return err
|
||||
nat11IPs := GetFlags().NAT11IPs
|
||||
if len(nat11IPs) > 0 {
|
||||
settingEngine.SetNAT1To1IPs(nat11IPs, webrtc.ICECandidateTypeHost)
|
||||
}
|
||||
|
||||
muxPort := GetFlags().UDPMuxPort
|
||||
if muxPort > 0 {
|
||||
mux, err := ice.NewMultiUDPMuxFromPort(muxPort)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
settingEngine.SetICEUDPMux(mux)
|
||||
} else {
|
||||
// Set the UDP port range used by WebRTC
|
||||
err = settingEngine.SetEphemeralUDPPortRange(uint16(flags.WebRTCUDPStart), uint16(flags.WebRTCUDPEnd))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
settingEngine.SetIncludeLoopbackCandidate(true) // Just in case
|
||||
|
||||
// Create a new API object with our customized settings
|
||||
globalWebRTCAPI = webrtc.NewAPI(webrtc.WithMediaEngine(mediaEngine), webrtc.WithSettingEngine(settingEngine), webrtc.WithInterceptorRegistry(interceptorRegistry))
|
||||
|
||||
@@ -88,7 +105,7 @@ func CreatePeerConnection(onClose func()) (*webrtc.PeerConnection, error) {
|
||||
if connectionState == webrtc.PeerConnectionStateFailed ||
|
||||
connectionState == webrtc.PeerConnectionStateDisconnected ||
|
||||
connectionState == webrtc.PeerConnectionStateClosed {
|
||||
err := pc.Close()
|
||||
err = pc.Close()
|
||||
if err != nil {
|
||||
log.Printf("Error closing PeerConnection: %s\n", err.Error())
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func participantHandler(participant *Participant, room *Room) {
|
||||
}
|
||||
|
||||
// Data channel settings
|
||||
settingOrdered := false
|
||||
settingOrdered := true
|
||||
settingMaxRetransmits := uint16(0)
|
||||
dc, err := participant.PeerConnection.CreateDataChannel("data", &webrtc.DataChannelInit{
|
||||
Ordered: &settingOrdered,
|
||||
@@ -75,13 +75,10 @@ func participantHandler(participant *Participant, room *Room) {
|
||||
log.Printf("Failed to marshal input message for participant: '%s' in room: '%s' - reason: %s\n", participant.ID, room.Name, err)
|
||||
return
|
||||
}
|
||||
if err = room.DataChannel.SendBinary(data); err != nil {
|
||||
log.Printf("Failed to send input message to room: '%s' - reason: %s\n", room.Name, err)
|
||||
}
|
||||
} else {
|
||||
if err = room.DataChannel.SendBinary(data); err != nil {
|
||||
log.Printf("Failed to send input message to room: '%s' - reason: %s\n", room.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err = room.DataChannel.SendBinary(data); err != nil {
|
||||
log.Printf("Failed to send input message to room: '%s' - reason: %s\n", room.Name, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -2,22 +2,28 @@ package relay
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"github.com/pion/webrtc/v4"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/pion/webrtc/v4"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var globalFlags *Flags
|
||||
|
||||
type Flags struct {
|
||||
Verbose bool
|
||||
Debug bool
|
||||
EndpointPort int
|
||||
WebRTCUDPStart int
|
||||
WebRTCUDPEnd int
|
||||
STUNServer string
|
||||
Verbose bool // Verbose mode - log more information to console
|
||||
Debug bool // Debug mode - log deeper debug information to console
|
||||
EndpointPort int // Port for HTTP/S and WS/S endpoint (TCP)
|
||||
WebRTCUDPStart int // WebRTC UDP port range start - ignored if UDPMuxPort is set
|
||||
WebRTCUDPEnd int // WebRTC UDP port range end - ignored if UDPMuxPort is set
|
||||
STUNServer string // WebRTC STUN server
|
||||
UDPMuxPort int // WebRTC UDP mux port - if set, overrides UDP port range
|
||||
AutoAddLocalIP bool // Automatically add local IP to NAT 1 to 1 IPs
|
||||
NAT11IPs []string // WebRTC NAT 1 to 1 IP(s) - allows specifying host IP(s) if behind NAT
|
||||
TLSCert string // Path to TLS certificate
|
||||
TLSKey string // Path to TLS key
|
||||
}
|
||||
|
||||
func (flags *Flags) DebugLog() {
|
||||
@@ -28,6 +34,13 @@ func (flags *Flags) DebugLog() {
|
||||
log.Println("> WebRTC UDP Range Start: ", flags.WebRTCUDPStart)
|
||||
log.Println("> WebRTC UDP Range End: ", flags.WebRTCUDPEnd)
|
||||
log.Println("> WebRTC STUN Server: ", flags.STUNServer)
|
||||
log.Println("> WebRTC UDP Mux Port: ", flags.UDPMuxPort)
|
||||
log.Println("> Auto Add Local IP: ", flags.AutoAddLocalIP)
|
||||
for i, ip := range flags.NAT11IPs {
|
||||
log.Printf("> WebRTC NAT 1 to 1 IP (%d): %s\n", i, ip)
|
||||
}
|
||||
log.Println("> Path to TLS Cert: ", flags.TLSCert)
|
||||
log.Println("> Path to TLS Key: ", flags.TLSKey)
|
||||
}
|
||||
|
||||
func getEnvAsInt(name string, defaultVal int) int {
|
||||
@@ -66,6 +79,13 @@ func InitFlags() {
|
||||
flag.IntVar(&globalFlags.WebRTCUDPStart, "webrtcUDPStart", getEnvAsInt("WEBRTC_UDP_START", 10000), "WebRTC UDP port range start")
|
||||
flag.IntVar(&globalFlags.WebRTCUDPEnd, "webrtcUDPEnd", getEnvAsInt("WEBRTC_UDP_END", 20000), "WebRTC UDP port range end")
|
||||
flag.StringVar(&globalFlags.STUNServer, "stunServer", getEnvAsString("STUN_SERVER", "stun.l.google.com:19302"), "WebRTC STUN server")
|
||||
flag.IntVar(&globalFlags.UDPMuxPort, "webrtcUDPMux", getEnvAsInt("WEBRTC_UDP_MUX", 8088), "WebRTC UDP mux port")
|
||||
flag.BoolVar(&globalFlags.AutoAddLocalIP, "autoAddLocalIP", getEnvAsBool("AUTO_ADD_LOCAL_IP", true), "Automatically add local IP to NAT 1 to 1 IPs")
|
||||
// String with comma separated IPs
|
||||
nat11IPs := ""
|
||||
flag.StringVar(&nat11IPs, "webrtcNAT11IPs", getEnvAsString("WEBRTC_NAT_IPS", ""), "WebRTC NAT 1 to 1 IP(s)")
|
||||
flag.StringVar(&globalFlags.TLSCert, "tlsCert", getEnvAsString("TLS_CERT", ""), "Path to TLS certificate")
|
||||
flag.StringVar(&globalFlags.TLSKey, "tlsKey", getEnvAsString("TLS_KEY", ""), "Path to TLS key")
|
||||
// Parse flags
|
||||
flag.Parse()
|
||||
|
||||
@@ -75,8 +95,44 @@ func InitFlags() {
|
||||
URLs: []string{"stun:" + globalFlags.STUNServer},
|
||||
},
|
||||
}
|
||||
|
||||
// Initialize NAT 1 to 1 IPs
|
||||
globalFlags.NAT11IPs = []string{}
|
||||
|
||||
// Get local IP
|
||||
if globalFlags.AutoAddLocalIP {
|
||||
globalFlags.NAT11IPs = append(globalFlags.NAT11IPs, getLocalIP())
|
||||
}
|
||||
|
||||
// Parse NAT 1 to 1 IPs from string
|
||||
if len(nat11IPs) > 0 {
|
||||
split := strings.Split(nat11IPs, ",")
|
||||
if len(split) > 0 {
|
||||
for _, ip := range split {
|
||||
globalFlags.NAT11IPs = append(globalFlags.NAT11IPs, ip)
|
||||
}
|
||||
} else {
|
||||
globalFlags.NAT11IPs = append(globalFlags.NAT11IPs, nat11IPs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GetFlags() *Flags {
|
||||
return globalFlags
|
||||
}
|
||||
|
||||
// getLocalIP returns local IP, be it either IPv4 or IPv6, skips loopback addresses
|
||||
func getLocalIP() string {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
for _, address := range addrs {
|
||||
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil || ipnet.IP != nil {
|
||||
return ipnet.IP.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package relay
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/gorilla/websocket"
|
||||
"log"
|
||||
"net/http"
|
||||
@@ -10,7 +11,7 @@ import (
|
||||
|
||||
var httpMux *http.ServeMux
|
||||
|
||||
func InitHTTPEndpoint() {
|
||||
func InitHTTPEndpoint() error {
|
||||
// Create HTTP mux which serves our WS endpoint
|
||||
httpMux = http.NewServeMux()
|
||||
|
||||
@@ -20,15 +21,30 @@ func InitHTTPEndpoint() {
|
||||
|
||||
// Get our serving port
|
||||
port := GetFlags().EndpointPort
|
||||
tlsCert := GetFlags().TLSCert
|
||||
tlsKey := GetFlags().TLSKey
|
||||
|
||||
// Log and start the endpoint server
|
||||
log.Println("Starting HTTP endpoint server on :", strconv.Itoa(port))
|
||||
go func() {
|
||||
log.Fatal((&http.Server{
|
||||
Handler: httpMux,
|
||||
Addr: ":" + strconv.Itoa(port),
|
||||
}).ListenAndServe())
|
||||
}()
|
||||
if len(tlsCert) <= 0 && len(tlsKey) <= 0 {
|
||||
log.Println("Starting HTTP endpoint server on :", strconv.Itoa(port))
|
||||
go func() {
|
||||
log.Fatal((&http.Server{
|
||||
Handler: httpMux,
|
||||
Addr: ":" + strconv.Itoa(port),
|
||||
}).ListenAndServe())
|
||||
}()
|
||||
} else if len(tlsCert) > 0 && len(tlsKey) > 0 {
|
||||
log.Println("Starting HTTPS endpoint server on :", strconv.Itoa(port))
|
||||
go func() {
|
||||
log.Fatal((&http.Server{
|
||||
Handler: httpMux,
|
||||
Addr: ":" + strconv.Itoa(port),
|
||||
}).ListenAndServeTLS(tlsCert, tlsKey))
|
||||
}()
|
||||
} else {
|
||||
return errors.New("no TLS certificate or TLS key provided")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// logHTTPError logs (if verbose) and sends an error code to requester
|
||||
|
||||
Reference in New Issue
Block a user