go-tunnel/server.go

94 lines
1.9 KiB
Go
Raw Permalink Normal View History

2020-10-21 18:00:15 +02:00
package tunnel
import (
"context"
"github.com/pkg/errors"
2020-10-26 19:42:07 +01:00
cmap "github.com/streamrail/concurrent-map"
2020-10-21 18:00:15 +02:00
"github.com/xtaci/kcp-go/v5"
"gitlab.com/wpetit/goweb/logger"
)
type Server struct {
conf *ServerConfig
clients cmap.ConcurrentMap
}
func (s *Server) Listen(ctx context.Context) error {
listener, err := kcp.ListenWithOptions(
s.conf.Address, s.conf.BlockCrypt,
s.conf.DataShards, s.conf.ParityShards,
)
if err != nil {
return errors.WithStack(err)
}
2020-10-26 19:42:07 +01:00
if s.conf.ConfigureListener != nil {
if err := s.conf.ConfigureListener(listener); err != nil {
return errors.WithStack(err)
}
}
logger.Debug(ctx, "accepting connections", logger.F("address", s.conf.Address))
2020-10-21 18:00:15 +02:00
for {
conn, err := listener.AcceptKCP()
if err != nil {
return errors.WithStack(err)
}
go s.handleNewConn(ctx, conn)
}
}
func (s *Server) handleNewConn(ctx context.Context, conn *kcp.UDPSession) {
2020-10-26 19:42:07 +01:00
var remoteClient *RemoteClient
remoteAddr := conn.RemoteAddr().String()
ctx = logger.With(ctx, logger.F("remoteAddr", remoteAddr))
rawExistingClient, exists := s.clients.Get(remoteAddr)
if exists {
logger.Debug(ctx, "remote client already exists")
remoteClient, _ = rawExistingClient.(*RemoteClient)
2020-10-21 18:00:15 +02:00
2020-10-26 19:42:07 +01:00
if err := remoteClient.SwitchConn(ctx, conn); err != nil {
logger.Error(ctx, "remote client error", logger.E(errors.WithStack(err)))
2020-10-24 13:35:27 +02:00
2020-10-26 19:42:07 +01:00
s.clients.Remove(remoteAddr)
return
}
}
remoteClient = NewRemoteClient(
s.conf.SmuxConfig,
s.conf.AuthenticationTimeout,
s.conf.ProxyRequestTimeout,
)
2020-10-21 18:00:15 +02:00
remoteClient.ConfigureHooks(s.conf.Hooks)
if err := remoteClient.Accept(ctx, conn); err != nil {
2020-10-24 13:35:27 +02:00
logger.Error(ctx, "remote client error", logger.E(errors.WithStack(err)))
2020-10-21 19:48:12 +02:00
return
2020-10-21 18:00:15 +02:00
}
2020-10-26 19:42:07 +01:00
s.clients.Set(remoteAddr, remoteClient)
2020-10-21 18:00:15 +02:00
}
func NewServer(funcs ...ServerConfigFunc) *Server {
conf := DefaultServerConfig()
for _, fn := range funcs {
fn(conf)
}
return &Server{
conf: conf,
clients: cmap.New(),
}
}