go-ssb-room/roomsrv/init_unixsock.go
Henry 7fa52a6e2d various fixes
* fix nav link
* fix roomstate lock and ticker
* fix copy pasta typos

web/handlers: stop using /testing/base in news

This was a brainfart. The idea for a more minimal base template came
from another project with different frontend code.

This stopped us from seeing tempalting errors in the nav area.

Might want to scratch these tests alltogether and just have one place
with all the http tests.
2021-02-11 15:31:45 +01:00

112 lines
2.6 KiB
Go

// SPDX-License-Identifier: MIT
package roomsrv
import (
"fmt"
"net"
"os"
"path/filepath"
kitlog "github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"go.cryptoscope.co/muxrpc/v2"
"github.com/ssb-ngi-pointer/go-ssb-room/internal/netwraputil"
"github.com/ssb-ngi-pointer/go-ssb-room/internal/repo"
)
// WithUNIXSocket enables listening for muxrpc connections on a unix socket files ($repo/socket).
// This socket is not encrypted or authenticated since access to it is mediated by filesystem ownership.
func WithUNIXSocket(yes bool) Option {
return func(s *Server) error {
s.loadUnixSock = yes
return nil
}
}
func (s *Server) initUnixSock() error {
// this races because roomsrv might not be done with init yet
// TODO: refactor network peer code and make unixsock implement that (those will be inited late anyway)
if s.keyPair == nil {
return fmt.Errorf("roomsrv/unixsock: keypair is nil. please use unixSocket with LateOption")
}
spoofWrapper := netwraputil.SpoofRemoteAddress(s.keyPair.Feed.ID)
r := repo.New(s.repoPath)
sockPath := r.GetPath("socket")
// local clients (not using network package because we don't want conn limiting or advertising)
c, err := net.Dial("unix", sockPath)
if err == nil {
c.Close()
return fmt.Errorf("roomsrv: repo already in use, socket accepted connection")
}
os.Remove(sockPath)
os.MkdirAll(filepath.Dir(sockPath), 0700)
uxLis, err := net.Listen("unix", sockPath)
if err != nil {
return err
}
s.closers.Add(uxLis)
go func() {
for {
c, err := uxLis.Accept()
if err != nil {
if nerr, ok := err.(*net.OpError); ok {
if nerr.Err.Error() == "use of closed network connection" {
return
}
}
level.Warn(s.logger).Log("event", "unix sock accept failed", "err", err)
continue
}
wc, err := spoofWrapper(c)
if err != nil {
c.Close()
continue
}
for _, w := range s.postSecureWrappers {
var err error
wc, err = w(wc)
if err != nil {
level.Warn(s.logger).Log("err", err)
c.Close()
continue
}
}
go func(conn net.Conn) {
defer conn.Close()
pkr := muxrpc.NewPacker(conn)
h, err := s.master.MakeHandler(conn)
if err != nil {
level.Warn(s.logger).Log("event", "unix sock make handler", "err", err)
return
}
edp := muxrpc.Handle(pkr, h,
muxrpc.WithContext(s.rootCtx),
muxrpc.WithLogger(kitlog.NewNopLogger()),
)
srv := edp.(muxrpc.Server)
if err := srv.Serve(); err != nil {
level.Warn(s.logger).Log("conn", "serve exited", "err", err, "peer", conn.RemoteAddr())
}
edp.Terminate()
}(wc)
}
}()
return nil
}