-
Notifications
You must be signed in to change notification settings - Fork 7
/
option.go
157 lines (135 loc) · 5.55 KB
/
option.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright 2016 Mikio Hara. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tcpinfo
import (
"encoding/json"
"time"
"github.com/mikioh/tcpopt"
)
var (
_ json.Marshaler = &Info{}
_ tcpopt.Option = &Info{}
)
// An Info represents connection information.
//
// Only supported on Darwin, FreeBSD, Linux and NetBSD.
type Info struct {
State State `json:"state"` // connection state
Options []Option `json:"opts,omitempty"` // requesting options
PeerOptions []Option `json:"peer_opts,omitempty"` // options requested from peer
SenderMSS MaxSegSize `json:"snd_mss"` // maximum segment size for sender in bytes
ReceiverMSS MaxSegSize `json:"rcv_mss"` // maximum segment size for receiver in bytes
RTT time.Duration `json:"rtt"` // round-trip time
RTTVar time.Duration `json:"rttvar"` // round-trip time variation
RTO time.Duration `json:"rto"` // retransmission timeout
ATO time.Duration `json:"ato"` // delayed acknowledgement timeout [Linux only]
LastDataSent time.Duration `json:"last_data_sent"` // since last data sent [Linux only]
LastDataReceived time.Duration `json:"last_data_rcvd"` // since last data received [FreeBSD and Linux]
LastAckReceived time.Duration `json:"last_ack_rcvd"` // since last ack received [Linux only]
FlowControl *FlowControl `json:"flow_ctl,omitempty"` // flow control information
CongestionControl *CongestionControl `json:"cong_ctl,omitempty"` // congestion control information
Sys *SysInfo `json:"sys,omitempty"` // platform-specific information
}
// A FlowControl represents flow control information.
type FlowControl struct {
ReceiverWindow uint `json:"rcv_wnd"` // advertised receiver window in bytes
}
// A CongestionControl represents congestion control information.
type CongestionControl struct {
SenderSSThreshold uint `json:"snd_ssthresh"` // slow start threshold for sender in bytes or # of segments
ReceiverSSThreshold uint `json:"rcv_ssthresh"` // slow start threshold for receiver in bytes [Linux only]
SenderWindowBytes uint `json:"snd_cwnd_bytes"` // congestion window for sender in bytes [Darwin and FreeBSD]
SenderWindowSegs uint `json:"snd_cwnd_segs"` // congestion window for sender in # of segments [Linux and NetBSD]
}
// Level implements the Level method of tcpopt.Option interface.
func (i *Info) Level() int { return options[soInfo].level }
// Name implements the Name method of tcpopt.Option interface.
func (i *Info) Name() int { return options[soInfo].name }
// MarshalJSON implements the MarshalJSON method of json.Marshaler
// interface.
func (i *Info) MarshalJSON() ([]byte, error) {
raw := make(map[string]interface{})
raw["state"] = i.State.String()
if len(i.Options) > 0 {
opts := make(map[string]interface{})
for _, opt := range i.Options {
opts[opt.Kind().String()] = opt
}
raw["opts"] = opts
}
if len(i.PeerOptions) > 0 {
opts := make(map[string]interface{})
for _, opt := range i.PeerOptions {
opts[opt.Kind().String()] = opt
}
raw["peer_opts"] = opts
}
raw["snd_mss"] = i.SenderMSS
raw["rcv_mss"] = i.ReceiverMSS
raw["rtt"] = i.RTT
raw["rttvar"] = i.RTTVar
raw["rto"] = i.RTO
raw["ato"] = i.ATO
raw["last_data_sent"] = i.LastDataSent
raw["last_data_rcvd"] = i.LastDataReceived
raw["last_ack_rcvd"] = i.LastAckReceived
if i.FlowControl != nil {
raw["flow_ctl"] = i.FlowControl
}
if i.CongestionControl != nil {
raw["cong_ctl"] = i.CongestionControl
}
if i.Sys != nil {
raw["sys"] = i.Sys
}
return json.Marshal(&raw)
}
// A CCInfo represents raw information of congestion control
// algorithm.
//
// Only supported on Linux.
type CCInfo struct {
Raw []byte `json:"raw,omitempty"`
}
// Level implements the Level method of tcpopt.Option interface.
func (cci *CCInfo) Level() int { return options[soCCInfo].level }
// Name implements the Name method of tcpopt.Option interface.
func (cci *CCInfo) Name() int { return options[soCCInfo].name }
// Marshal implements the Marshal method of tcpopt.Option interface.
func (cci *CCInfo) Marshal() ([]byte, error) { return cci.Raw, nil }
func parseCCInfo(b []byte) (tcpopt.Option, error) { return &CCInfo{Raw: b}, nil }
// A CCAlgorithm represents a name of congestion control algorithm.
//
// Only supported on Linux.
type CCAlgorithm string
// Level implements the Level method of tcpopt.Option interface.
func (cca CCAlgorithm) Level() int { return options[soCCAlgo].level }
// Name implements the Name method of tcpopt.Option interface.
func (cca CCAlgorithm) Name() int { return options[soCCAlgo].name }
// Marshal implements the Marshal method of tcpopt.Option interface.
func (cca CCAlgorithm) Marshal() ([]byte, error) {
if cca == "" {
return nil, nil
}
return []byte(cca), nil
}
func parseCCAlgorithm(b []byte) (tcpopt.Option, error) { return CCAlgorithm(b), nil }
// A CCAlgorithmInfo represents congestion control algorithm
// information.
//
// Only supported on Linux.
type CCAlgorithmInfo interface {
Algorithm() string
}
// ParseCCAlgorithmInfo parses congestion control algorithm
// information.
//
// Only supported on Linux.
func ParseCCAlgorithmInfo(name string, b []byte) (CCAlgorithmInfo, error) {
ccai, err := parseCCAlgorithmInfo(name, b)
if err != nil {
return nil, err
}
return ccai, nil
}