forked from extern/smegmesh
dbc18bddc6
- Performing DAD to check if IPv6 address present before adding outselves to mesh - Changing name from wgmesh to smegmesh
126 lines
3.0 KiB
Go
126 lines
3.0 KiB
Go
package conn
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
|
|
"github.com/tim-beatham/smegmesh/pkg/conf"
|
|
logging "github.com/tim-beatham/smegmesh/pkg/log"
|
|
"github.com/tim-beatham/smegmesh/pkg/rpc"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials"
|
|
)
|
|
|
|
// ConnectionServer manages gRPC server peer connections
|
|
type ConnectionServer struct {
|
|
// server an instance of the grpc server
|
|
server *grpc.Server
|
|
// the ctrl service to manage node
|
|
ctrlProvider rpc.MeshCtrlServerServer
|
|
// the sync service to synchronise nodes
|
|
syncProvider rpc.SyncServiceServer
|
|
Conf *conf.DaemonConfiguration
|
|
listener net.Listener
|
|
}
|
|
|
|
// NewConnectionServerParams contains params for creating a new connection server
|
|
type NewConnectionServerParams struct {
|
|
Conf *conf.DaemonConfiguration
|
|
CtrlProvider rpc.MeshCtrlServerServer
|
|
SyncProvider rpc.SyncServiceServer
|
|
}
|
|
|
|
// NewConnectionServer: create a new gRPC connection server instance
|
|
func NewConnectionServer(params *NewConnectionServerParams) (*ConnectionServer, error) {
|
|
cert, err := tls.LoadX509KeyPair(params.Conf.CertificatePath, params.Conf.PrivateKeyPath)
|
|
|
|
if err != nil {
|
|
logging.Log.WriteErrorf("Failed to load key pair: %s\n", err.Error())
|
|
return nil, err
|
|
}
|
|
|
|
serverAuth := tls.RequireAndVerifyClientCert
|
|
|
|
if params.Conf.SkipCertVerification {
|
|
serverAuth = tls.RequireAnyClientCert
|
|
}
|
|
|
|
certPool := x509.NewCertPool()
|
|
|
|
if params.Conf.CaCertificatePath == "" {
|
|
return nil, errors.New("CA Cert is not specified")
|
|
}
|
|
|
|
caCert, err := os.ReadFile(params.Conf.CaCertificatePath)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if ok := certPool.AppendCertsFromPEM(caCert); !ok {
|
|
return nil, errors.New("could not parse PEM")
|
|
}
|
|
|
|
serverConfig := &tls.Config{
|
|
ClientAuth: serverAuth,
|
|
Certificates: []tls.Certificate{cert},
|
|
ClientCAs: certPool,
|
|
}
|
|
|
|
server := grpc.NewServer(
|
|
grpc.Creds(credentials.NewTLS(serverConfig)),
|
|
)
|
|
|
|
ctrlProvider := params.CtrlProvider
|
|
syncProvider := params.SyncProvider
|
|
|
|
connServer := ConnectionServer{
|
|
server: server,
|
|
ctrlProvider: ctrlProvider,
|
|
syncProvider: syncProvider,
|
|
Conf: params.Conf,
|
|
}
|
|
|
|
return &connServer, nil
|
|
}
|
|
|
|
// Listen for incoming requests. Returns an error if something went wrong.
|
|
func (s *ConnectionServer) Listen() error {
|
|
rpc.RegisterMeshCtrlServerServer(s.server, s.ctrlProvider)
|
|
rpc.RegisterSyncServiceServer(s.server, s.syncProvider)
|
|
|
|
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", s.Conf.GrpcPort))
|
|
s.listener = lis
|
|
|
|
logging.Log.WriteInfof("GRPC listening on %d\n", s.Conf.GrpcPort)
|
|
|
|
if err != nil {
|
|
logging.Log.WriteErrorf(err.Error())
|
|
return err
|
|
}
|
|
|
|
if err := s.server.Serve(lis); err != nil {
|
|
logging.Log.WriteErrorf(err.Error())
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Close closes the connection server. Returns an error
|
|
// if something went wrong whilst attempting to close the connection
|
|
func (c *ConnectionServer) Close() error {
|
|
var err error = nil
|
|
c.server.Stop()
|
|
|
|
if c.listener != nil {
|
|
err = c.listener.Close()
|
|
}
|
|
|
|
return err
|
|
}
|