From 572251449e765e880a0ec6bf1ea1099cfff75ccf Mon Sep 17 00:00:00 2001 From: Matthias Frei Date: Sat, 4 Nov 2023 18:09:32 +0100 Subject: [PATCH] hackathon: add server side plumbing --- .../control_plane/experimental/v1/BUILD.bazel | 12 ++++ bufgen/proto/control_plane/v1/BUILD.bazel | 23 +++++++ .../v1/control_planeconnect/BUILD.bazel | 17 +++++ bufgen/proto/crypto/v1/BUILD.bazel | 13 ++++ bufgen/proto/daemon/v1/BUILD.bazel | 15 +++++ .../proto/daemon/v1/daemonconnect/BUILD.bazel | 12 ++++ bufgen/proto/discovery/v1/BUILD.bazel | 12 ++++ .../discovery/v1/discoveryconnect/BUILD.bazel | 12 ++++ bufgen/proto/drkey/v1/BUILD.bazel | 12 ++++ bufgen/proto/gateway/v1/BUILD.bazel | 15 +++++ .../gateway/v1/gatewayconnect/BUILD.bazel | 12 ++++ bufgen/proto/hidden_segment/v1/BUILD.bazel | 14 ++++ .../v1/hidden_segmentconnect/BUILD.bazel | 12 ++++ control/beaconing/connect/BUILD.bazel | 13 ++++ control/beaconing/connect/server.go | 2 +- control/cmd/control/BUILD.bazel | 8 +++ control/cmd/control/main.go | 64 +++++++++++++++++-- control/segreg/connect/BUILD.bazel | 13 ++++ control/segreg/connect/server.go | 2 +- control/segreq/connect/BUILD.bazel | 13 ++++ control/segreq/connect/lookup.go | 2 +- control/trust/connect/BUILD.bazel | 14 ++++ go.mod | 1 + go.sum | 2 + go_deps.bzl | 6 ++ pkg/snet/squic/net.go | 36 +++++++---- private/app/appnet/infraenv.go | 6 +- private/ca/renewal/connect/BUILD.bazel | 14 ++++ private/ca/renewal/connect/renewal.go | 2 +- 29 files changed, 351 insertions(+), 28 deletions(-) create mode 100644 bufgen/proto/control_plane/experimental/v1/BUILD.bazel create mode 100644 bufgen/proto/control_plane/v1/BUILD.bazel create mode 100644 bufgen/proto/control_plane/v1/control_planeconnect/BUILD.bazel create mode 100644 bufgen/proto/crypto/v1/BUILD.bazel create mode 100644 bufgen/proto/daemon/v1/BUILD.bazel create mode 100644 bufgen/proto/daemon/v1/daemonconnect/BUILD.bazel create mode 100644 bufgen/proto/discovery/v1/BUILD.bazel create mode 100644 bufgen/proto/discovery/v1/discoveryconnect/BUILD.bazel create mode 100644 bufgen/proto/drkey/v1/BUILD.bazel create mode 100644 bufgen/proto/gateway/v1/BUILD.bazel create mode 100644 bufgen/proto/gateway/v1/gatewayconnect/BUILD.bazel create mode 100644 bufgen/proto/hidden_segment/v1/BUILD.bazel create mode 100644 bufgen/proto/hidden_segment/v1/hidden_segmentconnect/BUILD.bazel create mode 100644 control/beaconing/connect/BUILD.bazel create mode 100644 control/segreg/connect/BUILD.bazel create mode 100644 control/segreq/connect/BUILD.bazel create mode 100644 control/trust/connect/BUILD.bazel create mode 100644 private/ca/renewal/connect/BUILD.bazel diff --git a/bufgen/proto/control_plane/experimental/v1/BUILD.bazel b/bufgen/proto/control_plane/experimental/v1/BUILD.bazel new file mode 100644 index 0000000000..6ee9a3cec6 --- /dev/null +++ b/bufgen/proto/control_plane/experimental/v1/BUILD.bazel @@ -0,0 +1,12 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["seg_detached_extensions.pb.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/control_plane/experimental/v1", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + ], +) diff --git a/bufgen/proto/control_plane/v1/BUILD.bazel b/bufgen/proto/control_plane/v1/BUILD.bazel new file mode 100644 index 0000000000..5135b195b7 --- /dev/null +++ b/bufgen/proto/control_plane/v1/BUILD.bazel @@ -0,0 +1,23 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "cppki.pb.go", + "drkey.pb.go", + "renewal.pb.go", + "seg.pb.go", + "seg_extensions.pb.go", + "svc_resolution.pb.go", + ], + importpath = "github.com/scionproto/scion/bufgen/proto/control_plane/v1", + visibility = ["//visibility:public"], + deps = [ + "//pkg/proto/control_plane/experimental:go_default_library", + "//pkg/proto/crypto:go_default_library", + "//pkg/proto/drkey:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + ], +) diff --git a/bufgen/proto/control_plane/v1/control_planeconnect/BUILD.bazel b/bufgen/proto/control_plane/v1/control_planeconnect/BUILD.bazel new file mode 100644 index 0000000000..e01a1db80b --- /dev/null +++ b/bufgen/proto/control_plane/v1/control_planeconnect/BUILD.bazel @@ -0,0 +1,17 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "cppki.connect.go", + "drkey.connect.go", + "renewal.connect.go", + "seg.connect.go", + ], + importpath = "github.com/scionproto/scion/bufgen/proto/control_plane/v1/control_planeconnect", + visibility = ["//visibility:public"], + deps = [ + "//pkg/proto/control_plane:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/bufgen/proto/crypto/v1/BUILD.bazel b/bufgen/proto/crypto/v1/BUILD.bazel new file mode 100644 index 0000000000..b495f4faea --- /dev/null +++ b/bufgen/proto/crypto/v1/BUILD.bazel @@ -0,0 +1,13 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["signed.pb.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/crypto/v1", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + ], +) diff --git a/bufgen/proto/daemon/v1/BUILD.bazel b/bufgen/proto/daemon/v1/BUILD.bazel new file mode 100644 index 0000000000..3f735c7b74 --- /dev/null +++ b/bufgen/proto/daemon/v1/BUILD.bazel @@ -0,0 +1,15 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["daemon.pb.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/daemon/v1", + visibility = ["//visibility:public"], + deps = [ + "//pkg/proto/drkey:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + "@org_golang_google_protobuf//types/known/durationpb:go_default_library", + "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + ], +) diff --git a/bufgen/proto/daemon/v1/daemonconnect/BUILD.bazel b/bufgen/proto/daemon/v1/daemonconnect/BUILD.bazel new file mode 100644 index 0000000000..796b9b3ea8 --- /dev/null +++ b/bufgen/proto/daemon/v1/daemonconnect/BUILD.bazel @@ -0,0 +1,12 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["daemon.connect.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/daemon/v1/daemonconnect", + visibility = ["//visibility:public"], + deps = [ + "//pkg/proto/daemon:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/bufgen/proto/discovery/v1/BUILD.bazel b/bufgen/proto/discovery/v1/BUILD.bazel new file mode 100644 index 0000000000..472c538e6e --- /dev/null +++ b/bufgen/proto/discovery/v1/BUILD.bazel @@ -0,0 +1,12 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["discovery.pb.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/discovery/v1", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + ], +) diff --git a/bufgen/proto/discovery/v1/discoveryconnect/BUILD.bazel b/bufgen/proto/discovery/v1/discoveryconnect/BUILD.bazel new file mode 100644 index 0000000000..89bbbb1e7f --- /dev/null +++ b/bufgen/proto/discovery/v1/discoveryconnect/BUILD.bazel @@ -0,0 +1,12 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["discovery.connect.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/discovery/v1/discoveryconnect", + visibility = ["//visibility:public"], + deps = [ + "//pkg/proto/discovery:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/bufgen/proto/drkey/v1/BUILD.bazel b/bufgen/proto/drkey/v1/BUILD.bazel new file mode 100644 index 0000000000..5b2210cfa5 --- /dev/null +++ b/bufgen/proto/drkey/v1/BUILD.bazel @@ -0,0 +1,12 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["drkey.pb.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/drkey/v1", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + ], +) diff --git a/bufgen/proto/gateway/v1/BUILD.bazel b/bufgen/proto/gateway/v1/BUILD.bazel new file mode 100644 index 0000000000..78129c1d74 --- /dev/null +++ b/bufgen/proto/gateway/v1/BUILD.bazel @@ -0,0 +1,15 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "control.pb.go", + "prefix.pb.go", + ], + importpath = "github.com/scionproto/scion/bufgen/proto/gateway/v1", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + ], +) diff --git a/bufgen/proto/gateway/v1/gatewayconnect/BUILD.bazel b/bufgen/proto/gateway/v1/gatewayconnect/BUILD.bazel new file mode 100644 index 0000000000..f8a805dae0 --- /dev/null +++ b/bufgen/proto/gateway/v1/gatewayconnect/BUILD.bazel @@ -0,0 +1,12 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["prefix.connect.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/gateway/v1/gatewayconnect", + visibility = ["//visibility:public"], + deps = [ + "//pkg/proto/gateway:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/bufgen/proto/hidden_segment/v1/BUILD.bazel b/bufgen/proto/hidden_segment/v1/BUILD.bazel new file mode 100644 index 0000000000..d31e95e94e --- /dev/null +++ b/bufgen/proto/hidden_segment/v1/BUILD.bazel @@ -0,0 +1,14 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["hidden_segment.pb.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/hidden_segment/v1", + visibility = ["//visibility:public"], + deps = [ + "//pkg/proto/control_plane:go_default_library", + "//pkg/proto/crypto:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", + ], +) diff --git a/bufgen/proto/hidden_segment/v1/hidden_segmentconnect/BUILD.bazel b/bufgen/proto/hidden_segment/v1/hidden_segmentconnect/BUILD.bazel new file mode 100644 index 0000000000..043a430166 --- /dev/null +++ b/bufgen/proto/hidden_segment/v1/hidden_segmentconnect/BUILD.bazel @@ -0,0 +1,12 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["hidden_segment.connect.go"], + importpath = "github.com/scionproto/scion/bufgen/proto/hidden_segment/v1/hidden_segmentconnect", + visibility = ["//visibility:public"], + deps = [ + "//pkg/proto/hidden_segment:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/control/beaconing/connect/BUILD.bazel b/control/beaconing/connect/BUILD.bazel new file mode 100644 index 0000000000..6227377850 --- /dev/null +++ b/control/beaconing/connect/BUILD.bazel @@ -0,0 +1,13 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["server.go"], + importpath = "github.com/scionproto/scion/control/beaconing/connect", + visibility = ["//visibility:public"], + deps = [ + "//control/beaconing/grpc:go_default_library", + "//pkg/proto/control_plane:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/control/beaconing/connect/server.go b/control/beaconing/connect/server.go index 1eb8c9718c..c0114fc652 100644 --- a/control/beaconing/connect/server.go +++ b/control/beaconing/connect/server.go @@ -9,7 +9,7 @@ import ( ) type SegmentCreationServer struct { - grpc.SegmentCreationServer + *grpc.SegmentCreationServer } func (s SegmentCreationServer) Beacon(ctx context.Context, req *connect.Request[control_plane.BeaconRequest]) (*connect.Response[control_plane.BeaconResponse], error) { diff --git a/control/cmd/control/BUILD.bazel b/control/cmd/control/BUILD.bazel index 5d2dfa81ea..f9e7a77846 100644 --- a/control/cmd/control/BUILD.bazel +++ b/control/cmd/control/BUILD.bazel @@ -10,9 +10,11 @@ go_library( importpath = "github.com/scionproto/scion/control/cmd/control", visibility = ["//visibility:private"], deps = [ + "//bufgen/proto/control_plane/v1/control_planeconnect:go_default_library", "//control:go_default_library", "//control/beacon:go_default_library", "//control/beaconing:go_default_library", + "//control/beaconing/connect:go_default_library", "//control/beaconing/grpc:go_default_library", "//control/config:go_default_library", "//control/drkey:go_default_library", @@ -20,8 +22,10 @@ go_library( "//control/ifstate:go_default_library", "//control/mgmtapi:go_default_library", "//control/onehop:go_default_library", + "//control/segreg/connect:go_default_library", "//control/segreg/grpc:go_default_library", "//control/segreq:go_default_library", + "//control/segreq/connect:go_default_library", "//control/segreq/grpc:go_default_library", "//control/trust:go_default_library", "//control/trust/grpc:go_default_library", @@ -38,6 +42,7 @@ go_library( "//pkg/scrypto:go_default_library", "//pkg/scrypto/cppki:go_default_library", "//pkg/snet:go_default_library", + "//pkg/snet/squic:go_default_library", "//private/app:go_default_library", "//private/app/appnet:go_default_library", "//private/app/command:go_default_library", @@ -45,6 +50,7 @@ go_library( "//private/ca/api:go_default_library", "//private/ca/config:go_default_library", "//private/ca/renewal:go_default_library", + "//private/ca/renewal/connect:go_default_library", "//private/ca/renewal/grpc:go_default_library", "//private/discovery:go_default_library", "//private/drkey/drkeyutil:go_default_library", @@ -71,6 +77,8 @@ go_library( "@com_github_go_chi_chi_v5//:go_default_library", "@com_github_go_chi_cors//:go_default_library", "@com_github_grpc_ecosystem_go_grpc_prometheus//:go_default_library", + "@com_github_quic_go_quic_go//:go_default_library", + "@com_github_quic_go_quic_go//http3:go_default_library", "@com_github_spf13_cobra//:go_default_library", "@in_gopkg_yaml_v2//:go_default_library", "@org_go4_netipx//:go_default_library", diff --git a/control/cmd/control/main.go b/control/cmd/control/main.go index c5e4c70a52..63ae5e0ec8 100644 --- a/control/cmd/control/main.go +++ b/control/cmd/control/main.go @@ -30,6 +30,8 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/cors" promgrpc "github.com/grpc-ecosystem/go-grpc-prometheus" + "github.com/quic-go/quic-go" + "github.com/quic-go/quic-go/http3" "github.com/spf13/cobra" "go4.org/netipx" "golang.org/x/sync/errgroup" @@ -37,9 +39,11 @@ import ( "google.golang.org/grpc/health" healthpb "google.golang.org/grpc/health/grpc_health_v1" + cpconnect "github.com/scionproto/scion/bufgen/proto/control_plane/v1/control_planeconnect" cs "github.com/scionproto/scion/control" "github.com/scionproto/scion/control/beacon" "github.com/scionproto/scion/control/beaconing" + beaconingconnect "github.com/scionproto/scion/control/beaconing/connect" beaconinggrpc "github.com/scionproto/scion/control/beaconing/grpc" "github.com/scionproto/scion/control/config" "github.com/scionproto/scion/control/drkey" @@ -47,8 +51,10 @@ import ( "github.com/scionproto/scion/control/ifstate" api "github.com/scionproto/scion/control/mgmtapi" "github.com/scionproto/scion/control/onehop" + segregconnect "github.com/scionproto/scion/control/segreg/connect" segreggrpc "github.com/scionproto/scion/control/segreg/grpc" "github.com/scionproto/scion/control/segreq" + segreqconnect "github.com/scionproto/scion/control/segreq/connect" segreqgrpc "github.com/scionproto/scion/control/segreq/grpc" cstrust "github.com/scionproto/scion/control/trust" cstrustgrpc "github.com/scionproto/scion/control/trust/grpc" @@ -65,6 +71,7 @@ import ( "github.com/scionproto/scion/pkg/scrypto" "github.com/scionproto/scion/pkg/scrypto/cppki" "github.com/scionproto/scion/pkg/snet" + "github.com/scionproto/scion/pkg/snet/squic" "github.com/scionproto/scion/private/app" infraenv "github.com/scionproto/scion/private/app/appnet" "github.com/scionproto/scion/private/app/command" @@ -72,6 +79,7 @@ import ( caapi "github.com/scionproto/scion/private/ca/api" caconfig "github.com/scionproto/scion/private/ca/config" "github.com/scionproto/scion/private/ca/renewal" + renewalconnect "github.com/scionproto/scion/private/ca/renewal/connect" renewalgrpc "github.com/scionproto/scion/private/ca/renewal/grpc" "github.com/scionproto/scion/private/discovery" "github.com/scionproto/scion/private/drkey/drkeyutil" @@ -317,6 +325,7 @@ func realMain(ctx context.Context) error { libgrpc.UnaryServerInterceptor(), libgrpc.DefaultMaxConcurrentStreams(), ) + connectMux := http.NewServeMux() tcpServer := grpc.NewServer( libgrpc.UnaryServerInterceptor(), libgrpc.DefaultMaxConcurrentStreams(), @@ -328,11 +337,13 @@ func realMain(ctx context.Context) error { IA: topo.IA(), Requests: libmetrics.NewPromCounter(cstrustmetrics.Handler.Requests), } + // TODO needs a wrapper here... + connectMux.Handle(cpconnect.NewTrustMaterialServiceHandler(nil)) cppb.RegisterTrustMaterialServiceServer(quicServer, trustServer) cppb.RegisterTrustMaterialServiceServer(tcpServer, trustServer) // Handle beaconing. - cppb.RegisterSegmentCreationServiceServer(quicServer, &beaconinggrpc.SegmentCreationServer{ + segmentCreationServer := &beaconinggrpc.SegmentCreationServer{ Handler: &beaconing.Handler{ LocalIA: topo.IA(), Inserter: beaconStore, @@ -340,7 +351,9 @@ func realMain(ctx context.Context) error { Verifier: verifier, BeaconsHandled: libmetrics.NewPromCounter(metrics.BeaconingReceivedTotal), }, - }) + } + cppb.RegisterSegmentCreationServiceServer(quicServer, segmentCreationServer) + connectMux.Handle(cpconnect.NewSegmentCreationServiceHandler(beaconingconnect.SegmentCreationServer{SegmentCreationServer: segmentCreationServer})) // Handle segment lookup authLookupServer := &segreqgrpc.LookupServer{ @@ -372,13 +385,15 @@ func realMain(ctx context.Context) error { // Always register a forwarding lookup for AS internal requests. cppb.RegisterSegmentLookupServiceServer(tcpServer, forwardingLookupServer) + connectMux.Handle(cpconnect.NewSegmentLookupServiceHandler(segreqconnect.LookupServer{LookupServer: forwardingLookupServer})) if topo.Core() { cppb.RegisterSegmentLookupServiceServer(quicServer, authLookupServer) + connectMux.Handle(cpconnect.NewSegmentLookupServiceHandler(segreqconnect.LookupServer{LookupServer: authLookupServer})) } // Handle segment registration. if topo.Core() { - cppb.RegisterSegmentRegistrationServiceServer(quicServer, &segreggrpc.RegistrationServer{ + registrationServer := &segreggrpc.RegistrationServer{ LocalIA: topo.IA(), SegHandler: seghandler.Handler{ Verifier: &seghandler.DefaultVerifier{ @@ -390,8 +405,9 @@ func realMain(ctx context.Context) error { }, }, Registrations: libmetrics.NewPromCounter(metrics.SegmentRegistrationsTotal), - }) - + } + cppb.RegisterSegmentRegistrationServiceServer(quicServer, registrationServer) + connectMux.Handle(cpconnect.NewSegmentRegistrationServiceHandler(segregconnect.RegistrationServer{RegistrationServer: registrationServer})) } signer := cs.NewSigner(topo.IA(), trustDB, globalCfg.General.ConfigDir) @@ -512,6 +528,7 @@ func realMain(ctx context.Context) error { } cppb.RegisterChainRenewalServiceServer(quicServer, renewalServer) + connectMux.Handle(cpconnect.NewChainRenewalServiceHandler(renewalconnect.RenewalServer{RenewalServer: renewalServer})) cppb.RegisterChainRenewalServiceServer(tcpServer, renewalServer) } @@ -667,14 +684,47 @@ func realMain(ctx context.Context) error { promgrpc.Register(tcpServer) var cleanup app.Cleanup + connectServer := http3.Server{ + Handler: connectMux, + } + + grpcConns := make(chan quic.Connection) + g.Go(func() error { + defer log.HandlePanic() + // TODO can be generic function, demux mux by next proto + listener := quicStack.Listener + for { + conn, err := listener.Accept(context.Background()) + if err == quic.ErrServerClosed { + return http.ErrServerClosed + } + if err != nil { + return err + } + go func() { + defer log.HandlePanic() + + if conn.ConnectionState().TLS.NegotiatedProtocol == "h3" { + if err := connectServer.ServeQUICConn(conn); err != nil { + log.Debug(err.Error()) + } + } else { + grpcConns <- conn + } + }() + } + }) + g.Go(func() error { defer log.HandlePanic() - if err := quicServer.Serve(quicStack.Listener); err != nil { - return serrors.WrapStr("serving gRPC/QUIC API", err) + grpcListener := squic.NewConnListener(grpcConns) + if err := quicServer.Serve(grpcListener); err != nil { + return serrors.WrapStr("serving gRPC/TCP API", err) } return nil }) cleanup.Add(func() error { quicServer.GracefulStop(); return nil }) + g.Go(func() error { defer log.HandlePanic() if err := tcpServer.Serve(tcpStack); err != nil { diff --git a/control/segreg/connect/BUILD.bazel b/control/segreg/connect/BUILD.bazel new file mode 100644 index 0000000000..2b29c740f4 --- /dev/null +++ b/control/segreg/connect/BUILD.bazel @@ -0,0 +1,13 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["server.go"], + importpath = "github.com/scionproto/scion/control/segreg/connect", + visibility = ["//visibility:public"], + deps = [ + "//control/segreg/grpc:go_default_library", + "//pkg/proto/control_plane:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/control/segreg/connect/server.go b/control/segreg/connect/server.go index 549aa83390..02e01823c8 100644 --- a/control/segreg/connect/server.go +++ b/control/segreg/connect/server.go @@ -9,7 +9,7 @@ import ( ) type RegistrationServer struct { - grpc.RegistrationServer + *grpc.RegistrationServer } func (s RegistrationServer) SegmentsRegistration(ctx context.Context, req *connect.Request[control_plane.SegmentsRegistrationRequest]) (*connect.Response[control_plane.SegmentsRegistrationResponse], error) { diff --git a/control/segreq/connect/BUILD.bazel b/control/segreq/connect/BUILD.bazel new file mode 100644 index 0000000000..28be25d0a4 --- /dev/null +++ b/control/segreq/connect/BUILD.bazel @@ -0,0 +1,13 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["lookup.go"], + importpath = "github.com/scionproto/scion/control/segreq/connect", + visibility = ["//visibility:public"], + deps = [ + "//control/segreq/grpc:go_default_library", + "//pkg/proto/control_plane:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/control/segreq/connect/lookup.go b/control/segreq/connect/lookup.go index e3bd6f8c2c..20507ccbc4 100644 --- a/control/segreq/connect/lookup.go +++ b/control/segreq/connect/lookup.go @@ -9,7 +9,7 @@ import ( ) type LookupServer struct { - grpc.LookupServer + *grpc.LookupServer } func (s LookupServer) Segments(ctx context.Context, req *connect.Request[control_plane.SegmentsRequest]) (*connect.Response[control_plane.SegmentsResponse], error) { diff --git a/control/trust/connect/BUILD.bazel b/control/trust/connect/BUILD.bazel new file mode 100644 index 0000000000..6941ad7bd3 --- /dev/null +++ b/control/trust/connect/BUILD.bazel @@ -0,0 +1,14 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["material.go"], + importpath = "github.com/scionproto/scion/control/trust/connect", + visibility = ["//visibility:public"], + deps = [ + "//bufgen/proto/control_plane/v1/control_planeconnect:go_default_library", + "//control/trust/grpc:go_default_library", + "//pkg/proto/control_plane:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/go.mod b/go.mod index 788b9fc230..0614a490ea 100644 --- a/go.mod +++ b/go.mod @@ -100,6 +100,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect + github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.4.1 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index f1f1756bf9..c7d0a243e5 100644 --- a/go.sum +++ b/go.sum @@ -366,6 +366,8 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= github.com/quic-go/quic-go v0.40.0 h1:GYd1iznlKm7dpHD7pOVpUvItgMPo/jrMgDWZhMCecqw= diff --git a/go_deps.bzl b/go_deps.bzl index 20859e8d18..b1e6e04852 100644 --- a/go_deps.bzl +++ b/go_deps.bzl @@ -13,6 +13,12 @@ def go_deps(): sum = "h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34=", version = "v0.3.2", ) + go_repository( + name = "com_connectrpc_connect", + importpath = "connectrpc.com/connect", + sum = "h1:HwKdOY0lGhhoHdsza+hW55aqHEC64pYpObRNoAgn70g=", + version = "v1.12.0", + ) go_repository( name = "com_github_alecthomas_template", importpath = "github.com/alecthomas/template", diff --git a/pkg/snet/squic/net.go b/pkg/snet/squic/net.go index 1994646392..65500d213f 100644 --- a/pkg/snet/squic/net.go +++ b/pkg/snet/squic/net.go @@ -46,48 +46,56 @@ const ( // streamAcceptTimeout is the default timeout for accepting connections. const streamAcceptTimeout = 5 * time.Second +// TODO: move this ? // ConnListener wraps a quic.Listener as a net.Listener. type ConnListener struct { - *quic.Listener + Conns <-chan quic.Connection ctx context.Context cancel func() } // NewConnListener constructs a new listener with the appropriate buffers set. -func NewConnListener(l *quic.Listener) *ConnListener { +func NewConnListener(conns <-chan quic.Connection) *ConnListener { ctx, cancel := context.WithCancel(context.Background()) c := &ConnListener{ - Listener: l, - ctx: ctx, - cancel: cancel, + Conns: conns, + ctx: ctx, + cancel: cancel, } return c } +func (l *ConnListener) Addr() net.Addr { + // TODO + return nil +} + // Accept accepts the first stream on a session and wraps it as a net.Conn. func (l *ConnListener) Accept() (net.Conn, error) { - session, err := l.Listener.Accept(l.ctx) - if err != nil { - return nil, err + select { + case conn := <-l.Conns: + return newAcceptingConn(l.ctx, conn), nil + case <-l.ctx.Done(): + return nil, l.ctx.Err() } - return newAcceptingConn(l.ctx, session), nil } // AcceptCtx accepts the first stream on a session and wraps it as a net.Conn. Accepts a context in // case the caller doesn't want this to block indefinitely. func (l *ConnListener) AcceptCtx(ctx context.Context) (net.Conn, error) { - session, err := l.Listener.Accept(ctx) - if err != nil { - return nil, err + select { + case conn := <-l.Conns: + return newAcceptingConn(ctx, conn), nil + case <-ctx.Done(): + return nil, ctx.Err() } - return newAcceptingConn(ctx, session), nil } // Close closes the listener. func (l *ConnListener) Close() error { l.cancel() - return l.Listener.Close() + return nil } // acceptingConn is a net.Conn wrapper for a QUIC stream that is yet to diff --git a/private/app/appnet/infraenv.go b/private/app/appnet/infraenv.go index e1f73c73c2..9a7608e067 100644 --- a/private/app/appnet/infraenv.go +++ b/private/app/appnet/infraenv.go @@ -89,7 +89,7 @@ type NetworkConfig struct { // QUICStack contains everything to run a QUIC based RPC stack. type QUICStack struct { - Listener *squic.ConnListener + Listener *quic.Listener InsecureDialer *squic.ConnDialer Dialer *squic.ConnDialer RedirectCloser func() @@ -119,7 +119,7 @@ func (nc *NetworkConfig) QUICStack() (*QUICStack, error) { InsecureSkipVerify: true, GetCertificate: nc.QUIC.GetCertificate, ClientAuth: tls.RequestClientCert, - NextProtos: []string{"SCION"}, + NextProtos: []string{"h3", "SCION"}, } listener, err := quic.Listen(server, serverTLSConfig, nil) @@ -155,7 +155,7 @@ func (nc *NetworkConfig) QUICStack() (*QUICStack, error) { } return &QUICStack{ - Listener: squic.NewConnListener(listener), + Listener: listener, InsecureDialer: &squic.ConnDialer{ Transport: clientTransport, TLSConfig: insecureClientTLSConfig, diff --git a/private/ca/renewal/connect/BUILD.bazel b/private/ca/renewal/connect/BUILD.bazel new file mode 100644 index 0000000000..29e6b9e65d --- /dev/null +++ b/private/ca/renewal/connect/BUILD.bazel @@ -0,0 +1,14 @@ +load("//tools/lint:go.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["renewal.go"], + importpath = "github.com/scionproto/scion/private/ca/renewal/connect", + visibility = ["//visibility:public"], + deps = [ + "//bufgen/proto/control_plane/v1/control_planeconnect:go_default_library", + "//pkg/proto/control_plane:go_default_library", + "//private/ca/renewal/grpc:go_default_library", + "@com_connectrpc_connect//:go_default_library", + ], +) diff --git a/private/ca/renewal/connect/renewal.go b/private/ca/renewal/connect/renewal.go index 5a14a19bb2..5dcada7615 100644 --- a/private/ca/renewal/connect/renewal.go +++ b/private/ca/renewal/connect/renewal.go @@ -12,7 +12,7 @@ import ( var _ control_planeconnect.ChainRenewalServiceHandler = RenewalServer{} type RenewalServer struct { - grpc.RenewalServer + *grpc.RenewalServer } func (m RenewalServer) ChainRenewal(ctx context.Context, req *connect.Request[control_plane.ChainRenewalRequest]) (*connect.Response[control_plane.ChainRenewalResponse], error) {