|
|
|
@ -66,6 +66,7 @@ type webRTCServerAPIConnsKickReq struct {
@@ -66,6 +66,7 @@ type webRTCServerAPIConnsKickReq struct {
|
|
|
|
|
type webRTCConnNewReq struct { |
|
|
|
|
pathName string |
|
|
|
|
wsconn *websocket.Conn |
|
|
|
|
res chan *webRTCConn |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type webRTCServerParent interface { |
|
|
|
@ -84,7 +85,6 @@ type webRTCServer struct {
@@ -84,7 +85,6 @@ type webRTCServer struct {
|
|
|
|
|
|
|
|
|
|
ctx context.Context |
|
|
|
|
ctxCancel func() |
|
|
|
|
wg sync.WaitGroup |
|
|
|
|
ln net.Listener |
|
|
|
|
udpMuxLn net.PacketConn |
|
|
|
|
tcpMuxLn net.Listener |
|
|
|
@ -99,6 +99,9 @@ type webRTCServer struct {
@@ -99,6 +99,9 @@ type webRTCServer struct {
|
|
|
|
|
chConnClose chan *webRTCConn |
|
|
|
|
chAPIConnsList chan webRTCServerAPIConnsListReq |
|
|
|
|
chAPIConnsKick chan webRTCServerAPIConnsKickReq |
|
|
|
|
|
|
|
|
|
// out
|
|
|
|
|
done chan struct{} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func newWebRTCServer( |
|
|
|
@ -182,6 +185,7 @@ func newWebRTCServer(
@@ -182,6 +185,7 @@ func newWebRTCServer(
|
|
|
|
|
chConnClose: make(chan *webRTCConn), |
|
|
|
|
chAPIConnsList: make(chan webRTCServerAPIConnsListReq), |
|
|
|
|
chAPIConnsKick: make(chan webRTCServerAPIConnsKickReq), |
|
|
|
|
done: make(chan struct{}), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
str := "listener opened on " + address + " (HTTP)" |
|
|
|
@ -197,7 +201,6 @@ func newWebRTCServer(
@@ -197,7 +201,6 @@ func newWebRTCServer(
|
|
|
|
|
s.metrics.webRTCServerSet(s) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s.wg.Add(1) |
|
|
|
|
go s.run() |
|
|
|
|
|
|
|
|
|
return s, nil |
|
|
|
@ -211,14 +214,17 @@ func (s *webRTCServer) log(level logger.Level, format string, args ...interface{
@@ -211,14 +214,17 @@ func (s *webRTCServer) log(level logger.Level, format string, args ...interface{
|
|
|
|
|
func (s *webRTCServer) close() { |
|
|
|
|
s.log(logger.Info, "listener is closing") |
|
|
|
|
s.ctxCancel() |
|
|
|
|
s.wg.Wait() |
|
|
|
|
<-s.done |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (s *webRTCServer) run() { |
|
|
|
|
defer s.wg.Done() |
|
|
|
|
defer close(s.done) |
|
|
|
|
|
|
|
|
|
rp := newHTTPRequestPool() |
|
|
|
|
defer rp.close() |
|
|
|
|
|
|
|
|
|
router := gin.New() |
|
|
|
|
router.NoRoute(httpLoggerMiddleware(s), s.onRequest) |
|
|
|
|
router.NoRoute(rp.mw, httpLoggerMiddleware(s), s.onRequest) |
|
|
|
|
|
|
|
|
|
tmp := make([]string, len(s.trustedProxies)) |
|
|
|
|
for i, entry := range s.trustedProxies { |
|
|
|
@ -238,6 +244,8 @@ func (s *webRTCServer) run() {
@@ -238,6 +244,8 @@ func (s *webRTCServer) run() {
|
|
|
|
|
go hs.Serve(s.ln) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var wg sync.WaitGroup |
|
|
|
|
|
|
|
|
|
outer: |
|
|
|
|
for { |
|
|
|
|
select { |
|
|
|
@ -248,7 +256,7 @@ outer:
@@ -248,7 +256,7 @@ outer:
|
|
|
|
|
req.pathName, |
|
|
|
|
req.wsconn, |
|
|
|
|
s.stunServers, |
|
|
|
|
&s.wg, |
|
|
|
|
&wg, |
|
|
|
|
s.pathManager, |
|
|
|
|
s, |
|
|
|
|
s.iceHostNAT1To1IPs, |
|
|
|
@ -256,6 +264,7 @@ outer:
@@ -256,6 +264,7 @@ outer:
|
|
|
|
|
s.iceTCPMux, |
|
|
|
|
) |
|
|
|
|
s.conns[c] = struct{}{} |
|
|
|
|
req.res <- c |
|
|
|
|
|
|
|
|
|
case conn := <-s.chConnClose: |
|
|
|
|
delete(s.conns, conn) |
|
|
|
@ -306,6 +315,8 @@ outer:
@@ -306,6 +315,8 @@ outer:
|
|
|
|
|
hs.Shutdown(context.Background()) |
|
|
|
|
s.ln.Close() // in case Shutdown() is called before Serve()
|
|
|
|
|
|
|
|
|
|
wg.Wait() |
|
|
|
|
|
|
|
|
|
if s.udpMuxLn != nil { |
|
|
|
|
s.udpMuxLn.Close() |
|
|
|
|
} |
|
|
|
@ -389,14 +400,29 @@ func (s *webRTCServer) onRequest(ctx *gin.Context) {
@@ -389,14 +400,29 @@ func (s *webRTCServer) onRequest(ctx *gin.Context) {
|
|
|
|
|
if err != nil { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
defer wsconn.Close() |
|
|
|
|
|
|
|
|
|
select { |
|
|
|
|
case s.connNew <- webRTCConnNewReq{ |
|
|
|
|
pathName: dir, |
|
|
|
|
wsconn: wsconn, |
|
|
|
|
}: |
|
|
|
|
case <-s.ctx.Done(): |
|
|
|
|
c := s.newConn(dir, wsconn) |
|
|
|
|
if c == nil { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
c.wait() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (s *webRTCServer) newConn(dir string, wsconn *websocket.Conn) *webRTCConn { |
|
|
|
|
req := webRTCConnNewReq{ |
|
|
|
|
pathName: dir, |
|
|
|
|
wsconn: wsconn, |
|
|
|
|
res: make(chan *webRTCConn), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
select { |
|
|
|
|
case s.connNew <- req: |
|
|
|
|
return <-req.res |
|
|
|
|
case <-s.ctx.Done(): |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|