1// +build !appengine
2
3/*
4 *
5 * Copyright 2018 gRPC authors.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *     http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21package service
22
23import (
24	"github.com/golang/protobuf/ptypes"
25	channelzpb "google.golang.org/grpc/channelz/grpc_channelz_v1"
26	"google.golang.org/grpc/internal/channelz"
27)
28
29func sockoptToProto(skopts *channelz.SocketOptionData) []*channelzpb.SocketOption {
30	var opts []*channelzpb.SocketOption
31	if skopts.Linger != nil {
32		additional, err := ptypes.MarshalAny(&channelzpb.SocketOptionLinger{
33			Active:   skopts.Linger.Onoff != 0,
34			Duration: convertToPtypesDuration(int64(skopts.Linger.Linger), 0),
35		})
36		if err == nil {
37			opts = append(opts, &channelzpb.SocketOption{
38				Name:       "SO_LINGER",
39				Additional: additional,
40			})
41		}
42	}
43	if skopts.RecvTimeout != nil {
44		additional, err := ptypes.MarshalAny(&channelzpb.SocketOptionTimeout{
45			Duration: convertToPtypesDuration(int64(skopts.RecvTimeout.Sec), int64(skopts.RecvTimeout.Usec)),
46		})
47		if err == nil {
48			opts = append(opts, &channelzpb.SocketOption{
49				Name:       "SO_RCVTIMEO",
50				Additional: additional,
51			})
52		}
53	}
54	if skopts.SendTimeout != nil {
55		additional, err := ptypes.MarshalAny(&channelzpb.SocketOptionTimeout{
56			Duration: convertToPtypesDuration(int64(skopts.SendTimeout.Sec), int64(skopts.SendTimeout.Usec)),
57		})
58		if err == nil {
59			opts = append(opts, &channelzpb.SocketOption{
60				Name:       "SO_SNDTIMEO",
61				Additional: additional,
62			})
63		}
64	}
65	if skopts.TCPInfo != nil {
66		additional, err := ptypes.MarshalAny(&channelzpb.SocketOptionTcpInfo{
67			TcpiState:       uint32(skopts.TCPInfo.State),
68			TcpiCaState:     uint32(skopts.TCPInfo.Ca_state),
69			TcpiRetransmits: uint32(skopts.TCPInfo.Retransmits),
70			TcpiProbes:      uint32(skopts.TCPInfo.Probes),
71			TcpiBackoff:     uint32(skopts.TCPInfo.Backoff),
72			TcpiOptions:     uint32(skopts.TCPInfo.Options),
73			// https://golang.org/pkg/syscall/#TCPInfo
74			// TCPInfo struct does not contain info about TcpiSndWscale and TcpiRcvWscale.
75			TcpiRto:          skopts.TCPInfo.Rto,
76			TcpiAto:          skopts.TCPInfo.Ato,
77			TcpiSndMss:       skopts.TCPInfo.Snd_mss,
78			TcpiRcvMss:       skopts.TCPInfo.Rcv_mss,
79			TcpiUnacked:      skopts.TCPInfo.Unacked,
80			TcpiSacked:       skopts.TCPInfo.Sacked,
81			TcpiLost:         skopts.TCPInfo.Lost,
82			TcpiRetrans:      skopts.TCPInfo.Retrans,
83			TcpiFackets:      skopts.TCPInfo.Fackets,
84			TcpiLastDataSent: skopts.TCPInfo.Last_data_sent,
85			TcpiLastAckSent:  skopts.TCPInfo.Last_ack_sent,
86			TcpiLastDataRecv: skopts.TCPInfo.Last_data_recv,
87			TcpiLastAckRecv:  skopts.TCPInfo.Last_ack_recv,
88			TcpiPmtu:         skopts.TCPInfo.Pmtu,
89			TcpiRcvSsthresh:  skopts.TCPInfo.Rcv_ssthresh,
90			TcpiRtt:          skopts.TCPInfo.Rtt,
91			TcpiRttvar:       skopts.TCPInfo.Rttvar,
92			TcpiSndSsthresh:  skopts.TCPInfo.Snd_ssthresh,
93			TcpiSndCwnd:      skopts.TCPInfo.Snd_cwnd,
94			TcpiAdvmss:       skopts.TCPInfo.Advmss,
95			TcpiReordering:   skopts.TCPInfo.Reordering,
96		})
97		if err == nil {
98			opts = append(opts, &channelzpb.SocketOption{
99				Name:       "TCP_INFO",
100				Additional: additional,
101			})
102		}
103	}
104	return opts
105}
106