Select Git revision
principalNetworkDomain.go
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
kmsetsi.go 5.16 KiB
package kms
import (
"context"
"errors"
"flag"
"fmt"
"net"
"time"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
pb "code.fbi.h-da.de/danet/proto-kms/api/gen/proto/go/kmsetsi"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
var (
etsiPort = flag.Int("port", 50900, "The server port")
)
// TODO: remove etsiServer
type etsiServer struct {
pb.UnimplementedKmsETSIServer
handlingEkms *EKMS
visitedKeys map[*kmsKSElement]bool
}
func (es *etsiServer) ETSICapabilities(ctx context.Context, in *pb.ETSICapabilitiesRequest) (capReply *pb.ETSICapabilitiesReply, err error) {
log.Debugf("Received: %v", in.GetMyKmsName())
return &pb.ETSICapabilitiesReply{
PeerKmsName: "whatever",
}, nil
}
func (es *etsiServer) ETSIGetQuantumInterfaces(ctx context.Context, in *pb.ETSIKMSQuantumInterfaceListRequest) (qleReply *pb.ETSIKMSQuantumInterfaceListReply, err error) {
qleList := make([]*pb.QuantumElementInfo, 1)
// Walk through QuantumLayerInterfaces and return their information
for _, qlWorks := range es.handlingEkms.quantumModules {
qleElement := pb.QuantumElementInfo{
QleID: qlWorks.ID().String(),
UdpAddr: qlWorks.Address().String(),
}
qleList = append(qleList, &qleElement)
}
return &pb.ETSIKMSQuantumInterfaceListReply{
QlElementInfo: qleList,
}, nil
}
func (es *etsiServer) ETSIAddKMSPeer(ctx context.Context, in *pb.ETSIKMSPeerRequest) (*pb.ETSIKMSPeerReply, error) {
//determine the kms structure to call
log.Debugf("AddKMSPeer called.")
// Check first if KmsLocalQLEId is actually one of ours...
qleID := uuid.MustParse(in.KmsLocalQLEId)
servingQLE, _ := es.handlingEkms.quantumModules[qleID]
if servingQLE == nil {
//no such element!
err := errors.New(fmt.Sprintf("Unknown local quantum element with ID %d", qleID))
return &pb.ETSIKMSPeerReply{}, err
}
//TODO: remove hardcoded id
es.handlingEkms.AddPeer("default", in.GetKmsPeerSocket(), servingQLE)
return &pb.ETSIKMSPeerReply{
KmsPeerName: es.handlingEkms.kmsName,
}, nil
}
func (es *etsiServer) ETSIRemoveKMSPeer(ctx context.Context, in *pb.ETSIKMSPeerRequest) (*pb.ETSIKMSPeerReply, error) {
//kms.RemovePeer(in.GetKmsPeerSocket())
return &pb.ETSIKMSPeerReply{
//KmsPeerName: kms.kmsName,
}, nil
}
func (es *etsiServer) ETSIGetPeerList(ctx context.Context, in *pb.ETSIKMSPeerListRequest) (*pb.ETSIKMSPeerListReply, error) {
ep := make([]*pb.ETSIKMSPeer, 2)
r := new(pb.ETSIKMSPeerListReply)
r.Peer = ep
p := pb.ETSIKMSPeer{
PeerName: "Yo",
PeerStatus: "bla",
}
r.Peer[0] = &p
return r, nil
}
func (es *etsiServer) ETSIAssignForwarding(ctx context.Context, in *pb.ETSIAssignForwardingRequest) (*pb.ETSIAssignForwardingReply, error) {
pathId, err := uuid.Parse(in.GetPathId())
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "The given path id %s is no uuid; err = ", in.GetPathId(), err)
}
var previousHop *kmsPeer
var nextHop *kmsPeer
var ok bool
if in.GetPrevHop() != "" {
previousHop, ok = es.handlingEkms.KmsPeers[in.GetPrevHop()]
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "No peer for %s", in.GetPrevHop())
}
}
if in.GetNextHop() != "" {
nextHop, ok = es.handlingEkms.KmsPeers[in.GetNextHop()]
if !ok {
return nil, status.Errorf(codes.InvalidArgument, "No peer for %s", in.GetNextHop())
}
}
// set the route within routing table
es.handlingEkms.routingTable[pathId] = &Route{
Previous: previousHop,
Next: nextHop,
}
log.Info("ROUTINGTABLE: ", es.handlingEkms.routingTable)
return &pb.ETSIAssignForwardingReply{
Timestamp: time.Now().Unix(),
}, nil
}
func (es *etsiServer) ETSISendPayload(ctx context.Context, in *pb.ETSISendPayloadRequest) (*pb.ETSISendPayloadResponse, error) {
pathId, err := uuid.Parse(in.GetPathId())
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "The given path id %s is no uuid; err = ", in.GetPathId(), err)
}
route, ok := es.handlingEkms.routingTable[pathId]
if !ok {
return nil, status.Errorf(codes.Internal, "No route found for path id: %s", in.GetPathId())
}
// NOTE: For demo purpose only
//json, err := json.Marshal(KMSInfo{
// Name: es.handlingEkms.kmsName,
// EncryptedMessage: in.Payload,
// DecryptedMessage: in.Payload,
//})
//if err != nil {
// log.Println("Failed to marshal: ", err)
//}
//err = sendKmsInfoMessage("http://172.20.10.21:4000/kmsinfo", json)
//if err != nil {
// log.Println("Failed to send KMS info message: ", err)
//}
if err := route.Next.SendPayload([]byte(in.GetPayload()), pathId); err != nil {
return nil, status.Errorf(codes.Internal, "Failed to send payload: ", err)
}
return &pb.ETSISendPayloadResponse{
Timestamp: time.Now().Unix(),
}, nil
}
func StartETSI(listenAddr string, callingKMS *EKMS) {
flag.Parse()
//lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *etsiPort))
lis, err := net.Listen("tcp", listenAddr)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterKmsETSIServer(s, &etsiServer{
handlingEkms: callingKMS,
visitedKeys: make(map[*kmsKSElement]bool),
})
log.Infof("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}