Make WSS link dial-only as TLS certs are not exposed to user

Signed-off-by: Vasyl Gello <vasek.gello@gmail.com>
This commit is contained in:
Vasyl Gello 2024-07-22 05:54:14 +03:00
parent 1f76d09a04
commit 6c02e30bc9

View file

@ -2,11 +2,9 @@ package core
import ( import (
"context" "context"
"crypto/tls" "fmt"
"net" "net"
"net/http"
"net/url" "net/url"
"time"
"github.com/Arceliar/phony" "github.com/Arceliar/phony"
"nhooyr.io/websocket" "nhooyr.io/websocket"
@ -14,7 +12,6 @@ import (
type linkWSS struct { type linkWSS struct {
phony.Inbox phony.Inbox
tlsconfig *tls.Config
*links *links
} }
@ -22,72 +19,9 @@ type linkWSSConn struct {
net.Conn net.Conn
} }
type linkWSSListener struct {
ch chan *linkWSSConn
ctx context.Context
httpServer *http.Server
listener net.Listener
tlslistener net.Listener
}
type wssServer struct {
ch chan *linkWSSConn
ctx context.Context
}
func (l *linkWSSListener) Accept() (net.Conn, error) {
qs := <-l.ch
if qs == nil {
return nil, context.Canceled
}
return qs, nil
}
func (l *linkWSSListener) Addr() net.Addr {
return l.listener.Addr()
}
func (l *linkWSSListener) Close() error {
if err := l.httpServer.Shutdown(l.ctx); err != nil {
return err
}
if err := l.tlslistener.Close(); err != nil {
return err
}
return l.listener.Close()
}
func (s *wssServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/h" {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
return
}
c, err := websocket.Accept(w, r, &websocket.AcceptOptions{
Subprotocols: []string{"ygg-ws"},
})
if err != nil {
return
}
if c.Subprotocol() != "ygg-ws" {
c.Close(websocket.StatusPolicyViolation, "client must speak the ygg-ws subprotocol")
return
}
netconn := websocket.NetConn(s.ctx, c, websocket.MessageBinary)
ch := s.ch
ch <- &linkWSSConn{
Conn: netconn,
}
}
func (l *links) newLinkWSS() *linkWSS { func (l *links) newLinkWSS() *linkWSS {
lwss := &linkWSS{ lwss := &linkWSS{
links: l, links: l,
tlsconfig: l.core.config.tls.Clone(),
} }
return lwss return lwss
@ -107,31 +41,5 @@ func (l *linkWSS) dial(ctx context.Context, url *url.URL, info linkInfo, options
} }
func (l *linkWSS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) { func (l *linkWSS) listen(ctx context.Context, url *url.URL, _ string) (net.Listener, error) {
nl, err := net.Listen("tcp", url.Host) return nil, fmt.Errorf("WSS listener not supported, use WS listener behind reverse proxy instead")
if err != nil {
return nil, err
}
tl := tls.NewListener(nl, l.tlsconfig)
ch := make(chan *linkWSSConn)
httpServer := &http.Server{
Handler: &wssServer{
ch: ch,
ctx: ctx,
},
ReadTimeout: time.Second * 10,
WriteTimeout: time.Second * 10,
}
lwl := &linkWSSListener{
ch: ch,
ctx: ctx,
httpServer: httpServer,
listener: nl,
tlslistener: tl,
}
go lwl.httpServer.Serve(tl)
return lwl, nil
} }