startNodeHub 实例化 nodehub.Hub 并构造 gRPC server(单端口 cmux 模式)。 TLS 监听和 cmux 分流由调用方负责;gRPC server 通过 Serve(grpcSubListener) 启动,keepalive 参数完全有效。 serverCN/serverSANs 用于自签服务器证书(节点 CA 信任链,节点无需额外配置)。 pushHandler 为 nil 时使用 NoopPushHandler。 失败仅打印 log:GRPCServer 为 nil 时不启用 gRPC 功能。
(ctx context.Context, serverCN string, serverSANs []string, nodeCA *cert.NodeCA, nodeStore nodes.Store, pushHandler nodehub.PushHandler)
| 34 | // |
| 35 | // 失败仅打印 log:GRPCServer 为 nil 时不启用 gRPC 功能。 |
| 36 | func startNodeHub(ctx context.Context, serverCN string, serverSANs []string, nodeCA *cert.NodeCA, nodeStore nodes.Store, pushHandler nodehub.PushHandler) *nodeHubResult { |
| 37 | if pushHandler == nil { |
| 38 | pushHandler = nodehub.NoopPushHandler{} |
| 39 | } |
| 40 | hub := nodehub.New(nodehub.Options{ |
| 41 | PushHandler: pushHandler, |
| 42 | DeadConnectionTimeout: 60 * time.Second, |
| 43 | ReaperInterval: 10 * time.Second, |
| 44 | OnNodeConnected: onNodeConnected(nodeStore), |
| 45 | }) |
| 46 | |
| 47 | serverTLS, err := nodeCA.IssueServerCert(serverCN, serverSANs, 365*24*time.Hour) |
| 48 | if err != nil { |
| 49 | log.Printf("nodehub: issue server cert failed: %v; gRPC disabled", err) |
| 50 | return &nodeHubResult{Hub: hub} |
| 51 | } |
| 52 | |
| 53 | // gRPC 使用真实 TLS 握手(cmux 按 TLS ClientHello 分流,握手在此完成)。 |
| 54 | // RequireAndVerifyClientCert 在 TLS 层强制 mTLS,无需额外的应用层拦截器。 |
| 55 | tlsCfg := &tls.Config{ |
| 56 | Certificates: []tls.Certificate{serverTLS}, |
| 57 | ClientAuth: tls.RequireAndVerifyClientCert, |
| 58 | ClientCAs: nodeCA.ClientCAPool(), |
| 59 | NextProtos: []string{"h2"}, |
| 60 | MinVersion: tls.VersionTLS12, |
| 61 | } |
| 62 | |
| 63 | grpcSrv := grpc.NewServer( |
| 64 | grpc.Creds(credentials.NewTLS(tlsCfg)), |
| 65 | grpc.KeepaliveParams(keepalive.ServerParameters{ |
| 66 | Time: 30 * time.Second, |
| 67 | Timeout: 10 * time.Second, |
| 68 | }), |
| 69 | grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ |
| 70 | MinTime: 25 * time.Second, |
| 71 | PermitWithoutStream: true, |
| 72 | }), |
| 73 | ) |
| 74 | nodev1.RegisterNodeAgentServer(grpcSrv, hub) |
| 75 | go hub.RunReaper(ctx) |
| 76 | |
| 77 | return &nodeHubResult{Hub: hub, GRPCServer: grpcSrv} |
| 78 | } |
| 79 | |
| 80 | // onNodeConnected 返回节点建连回调:用 gRPC 对端 IP 更新 node.BaseURL。 |
| 81 | // 仅更新 loopback 或空 BaseURL,保留管理员手动配置的域名。 |
no test coverage detected