...

Source file src/google.golang.org/grpc/channelz/internal/protoconv/socket.go

Documentation: google.golang.org/grpc/channelz/internal/protoconv

     1  /*
     2   *
     3   * Copyright 2024 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package protoconv
    20  
    21  import (
    22  	"net"
    23  	"time"
    24  
    25  	"google.golang.org/grpc/codes"
    26  	"google.golang.org/grpc/credentials"
    27  	"google.golang.org/grpc/internal/channelz"
    28  	"google.golang.org/grpc/status"
    29  	"google.golang.org/protobuf/types/known/anypb"
    30  	"google.golang.org/protobuf/types/known/timestamppb"
    31  	"google.golang.org/protobuf/types/known/wrapperspb"
    32  
    33  	channelzpb "google.golang.org/grpc/channelz/grpc_channelz_v1"
    34  )
    35  
    36  func securityToProto(se credentials.ChannelzSecurityValue) *channelzpb.Security {
    37  	switch v := se.(type) {
    38  	case *credentials.TLSChannelzSecurityValue:
    39  		return &channelzpb.Security{Model: &channelzpb.Security_Tls_{Tls: &channelzpb.Security_Tls{
    40  			CipherSuite:       &channelzpb.Security_Tls_StandardName{StandardName: v.StandardName},
    41  			LocalCertificate:  v.LocalCertificate,
    42  			RemoteCertificate: v.RemoteCertificate,
    43  		}}}
    44  	case *credentials.OtherChannelzSecurityValue:
    45  		otherSecurity := &channelzpb.Security_OtherSecurity{
    46  			Name: v.Name,
    47  		}
    48  		if anyval, err := anypb.New(v.Value); err == nil {
    49  			otherSecurity.Value = anyval
    50  		}
    51  		return &channelzpb.Security{Model: &channelzpb.Security_Other{Other: otherSecurity}}
    52  	}
    53  	return nil
    54  }
    55  
    56  func addrToProto(a net.Addr) *channelzpb.Address {
    57  	if a == nil {
    58  		return nil
    59  	}
    60  	switch a.Network() {
    61  	case "udp":
    62  		// TODO: Address_OtherAddress{}. Need proto def for Value.
    63  	case "ip":
    64  		// Note zone info is discarded through the conversion.
    65  		return &channelzpb.Address{Address: &channelzpb.Address_TcpipAddress{TcpipAddress: &channelzpb.Address_TcpIpAddress{IpAddress: a.(*net.IPAddr).IP}}}
    66  	case "ip+net":
    67  		// Note mask info is discarded through the conversion.
    68  		return &channelzpb.Address{Address: &channelzpb.Address_TcpipAddress{TcpipAddress: &channelzpb.Address_TcpIpAddress{IpAddress: a.(*net.IPNet).IP}}}
    69  	case "tcp":
    70  		// Note zone info is discarded through the conversion.
    71  		return &channelzpb.Address{Address: &channelzpb.Address_TcpipAddress{TcpipAddress: &channelzpb.Address_TcpIpAddress{IpAddress: a.(*net.TCPAddr).IP, Port: int32(a.(*net.TCPAddr).Port)}}}
    72  	case "unix", "unixgram", "unixpacket":
    73  		return &channelzpb.Address{Address: &channelzpb.Address_UdsAddress_{UdsAddress: &channelzpb.Address_UdsAddress{Filename: a.String()}}}
    74  	default:
    75  	}
    76  	return &channelzpb.Address{}
    77  }
    78  
    79  func socketToProto(skt *channelz.Socket) *channelzpb.Socket {
    80  	s := &channelzpb.Socket{}
    81  	s.Ref = &channelzpb.SocketRef{SocketId: skt.ID, Name: skt.RefName}
    82  
    83  	s.Data = &channelzpb.SocketData{
    84  		StreamsStarted:   skt.SocketMetrics.StreamsStarted.Load(),
    85  		StreamsSucceeded: skt.SocketMetrics.StreamsSucceeded.Load(),
    86  		StreamsFailed:    skt.SocketMetrics.StreamsFailed.Load(),
    87  		MessagesSent:     skt.SocketMetrics.MessagesSent.Load(),
    88  		MessagesReceived: skt.SocketMetrics.MessagesReceived.Load(),
    89  		KeepAlivesSent:   skt.SocketMetrics.KeepAlivesSent.Load(),
    90  	}
    91  	if ts := timestamppb.New(time.Unix(0, skt.SocketMetrics.LastLocalStreamCreatedTimestamp.Load())); ts.IsValid() {
    92  		s.Data.LastLocalStreamCreatedTimestamp = ts
    93  	}
    94  	if ts := timestamppb.New(time.Unix(0, skt.SocketMetrics.LastRemoteStreamCreatedTimestamp.Load())); ts.IsValid() {
    95  		s.Data.LastRemoteStreamCreatedTimestamp = ts
    96  	}
    97  	if ts := timestamppb.New(time.Unix(0, skt.SocketMetrics.LastMessageSentTimestamp.Load())); ts.IsValid() {
    98  		s.Data.LastMessageSentTimestamp = ts
    99  	}
   100  	if ts := timestamppb.New(time.Unix(0, skt.SocketMetrics.LastMessageReceivedTimestamp.Load())); ts.IsValid() {
   101  		s.Data.LastMessageReceivedTimestamp = ts
   102  	}
   103  	if skt.EphemeralMetrics != nil {
   104  		e := skt.EphemeralMetrics()
   105  		s.Data.LocalFlowControlWindow = wrapperspb.Int64(e.LocalFlowControlWindow)
   106  		s.Data.RemoteFlowControlWindow = wrapperspb.Int64(e.RemoteFlowControlWindow)
   107  	}
   108  
   109  	s.Data.Option = sockoptToProto(skt.SocketOptions)
   110  	s.Security = securityToProto(skt.Security)
   111  	s.Local = addrToProto(skt.LocalAddr)
   112  	s.Remote = addrToProto(skt.RemoteAddr)
   113  	s.RemoteName = skt.RemoteName
   114  	return s
   115  }
   116  
   117  // GetServerSockets returns the protobuf representation of the server (listen)
   118  // sockets starting at startID (max of len), and returns end=true if no server
   119  // sockets exist with higher IDs.
   120  func GetServerSockets(serverID, startID int64, len int) (sockets []*channelzpb.SocketRef, end bool) {
   121  	skts, end := channelz.GetServerSockets(serverID, startID, len)
   122  	for _, m := range skts {
   123  		sockets = append(sockets, &channelzpb.SocketRef{SocketId: m.ID, Name: m.RefName})
   124  	}
   125  	return sockets, end
   126  }
   127  
   128  // GetSocket returns the protobuf representation of the socket with the given
   129  // ID.
   130  func GetSocket(id int64) (*channelzpb.Socket, error) {
   131  	skt := channelz.GetSocket(id)
   132  	if skt == nil {
   133  		return nil, status.Errorf(codes.NotFound, "requested socket %d not found", id)
   134  	}
   135  	return socketToProto(skt), nil
   136  }
   137  

View as plain text