2020-10-21 18:00:15 +02:00
|
|
|
package tunnel
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
cmap "github.com/orcaman/concurrent-map"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"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)
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
|
|
|
ctx = logger.With(ctx, logger.F("remoteAddr", conn.RemoteAddr().String()))
|
|
|
|
|
|
|
|
remoteClient := NewRemoteClient()
|
2020-10-24 13:35:27 +02:00
|
|
|
|
2020-10-23 13:42:18 +02:00
|
|
|
defer remoteClient.Close()
|
2020-10-24 13:35:27 +02:00
|
|
|
defer conn.Close()
|
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
|
|
|
}
|
|
|
|
|
|
|
|
if err := remoteClient.Listen(ctx); err != nil {
|
2020-10-24 13:35:27 +02:00
|
|
|
logger.Error(ctx, "remote client error", logger.E(errors.WithStack(err)))
|
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(),
|
|
|
|
}
|
|
|
|
}
|