Skip to content

Commit

Permalink
add support for new command type
Browse files Browse the repository at this point in the history
Summary:
This adds support for `sourcename` requests. The intent is to to record the names of upstream peers without making DNS queries.

This uses [REQ_NTP_SOURCE_NAME](https://github.com/mlichvar/chrony/blob/e11b518a1ffa704986fb1f1835c425844ba248ef/candm.h#L105) in chronyc / chronyd protocol.

Reviewed By: abulimov, pmazzini

Differential Revision: D52958625

fbshipit-source-id: e80ee596833b6b39aa6550ee1d60e66481b40b79
  • Loading branch information
t3lurid3 authored and facebook-github-bot committed Jan 22, 2024
1 parent a6ceb6a commit 80c83be
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 17 deletions.
89 changes: 72 additions & 17 deletions ntp/chrony/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,26 +70,28 @@ func (t PacketType) String() string {

// request types. Only those we support, there are more
const (
reqNSources CommandType = 14
reqSourceData CommandType = 15
reqTracking CommandType = 33
reqSourceStats CommandType = 34
reqActivity CommandType = 44
reqServerStats CommandType = 54
reqNTPData CommandType = 57
reqNSources CommandType = 14
reqSourceData CommandType = 15
reqTracking CommandType = 33
reqSourceStats CommandType = 34
reqActivity CommandType = 44
reqServerStats CommandType = 54
reqNTPData CommandType = 57
reqNTPSourceName CommandType = 65
)

// reply types
const (
rpyNSources ReplyType = 2
rpySourceData ReplyType = 3
rpyTracking ReplyType = 5
rpySourceStats ReplyType = 6
rpyActivity ReplyType = 12
rpyServerStats ReplyType = 14
rpyNTPData ReplyType = 16
rpyServerStats2 ReplyType = 22
rpyServerStats3 ReplyType = 24
rpyNSources ReplyType = 2
rpySourceData ReplyType = 3
rpyTracking ReplyType = 5
rpySourceStats ReplyType = 6
rpyActivity ReplyType = 12
rpyServerStats ReplyType = 14
rpyNTPData ReplyType = 16
rpyNTPSourceName ReplyType = 19
rpyServerStats2 ReplyType = 22
rpyServerStats3 ReplyType = 24
)

// source modes
Expand Down Expand Up @@ -273,6 +275,15 @@ type RequestNTPData struct {
data [maxDataLen - 16]uint8
}

// RequestNTPSourceName - packet to request source name for peer IP.
type RequestNTPSourceName struct {
RequestHead
IPAddr ipAddr
EOR int32
// we pass at max ipv6 addr - 16 bytes
data [maxDataLen - 16]uint8
}

// RequestServerStats - packet to request server stats
type RequestServerStats struct {
RequestHead
Expand Down Expand Up @@ -590,12 +601,33 @@ func newNTPData(r *replyNTPDataContent) *NTPData {
}
}

// ReplyNTPData is a what end user will get for of 'ntp data' response
// ReplyNTPData is a what end user will get in 'ntp data' response
type ReplyNTPData struct {
ReplyHead
NTPData
}

type replyNTPSourceNameContent struct {
Name [256]uint8
}

// NTPSourceName contains parsed version of 'sourcename' reply
type NTPSourceName struct {
Name [256]uint8
}

func newNTPSourceName(r *replyNTPSourceNameContent) *NTPSourceName {
return &NTPSourceName{
Name: r.Name,
}
}

// ReplyNTPSourceName is a what end user will get in 'sourcename' response
type ReplyNTPSourceName struct {
ReplyHead
NTPSourceName
}

// Activity contains parsed version of 'activity' reply
type Activity struct {
Online int32
Expand Down Expand Up @@ -730,6 +762,19 @@ func NewNTPDataPacket(ip net.IP) *RequestNTPData {
}
}

// NewNTPSourceNamePacket creates new packet to request 'source name' information for given peer IP
func NewNTPSourceNamePacket(ip net.IP) *RequestNTPSourceName {
return &RequestNTPSourceName{
RequestHead: RequestHead{
Version: protoVersionNumber,
PKTType: pktTypeCmdRequest,
Command: reqNTPSourceName,
},
IPAddr: *newIPAddr(ip),
data: [maxDataLen - 16]uint8{},
}
}

// NewServerStatsPacket creates new packet to request 'serverstats' information
func NewServerStatsPacket() *RequestServerStats {
return &RequestServerStats{
Expand Down Expand Up @@ -837,6 +882,16 @@ func decodePacket(response []byte) (ResponsePacket, error) {
ReplyHead: *head,
NTPData: *newNTPData(data),
}, nil
case rpyNTPSourceName:
data := new(replyNTPSourceNameContent)
if err = binary.Read(r, binary.BigEndian, data); err != nil {
return nil, err
}
log.Debugf("response data: %+v", data)
return &ReplyNTPSourceName{
ReplyHead: *head,
NTPSourceName: *newNTPSourceName(data),
}, nil
case rpyServerStats2:
data := new(ServerStats2)
if err = binary.Read(r, binary.BigEndian, data); err != nil {
Expand Down
80 changes: 80 additions & 0 deletions ntp/chrony/packet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,86 @@ func TestDecodeNTPData(t *testing.T) {
require.Equal(t, want, packet)
}

func TestDecodeNTPSourceName(t *testing.T) {
raw := []uint8{
0x06, 0x02, 0x00, 0x00, 0x00, 0x41, 0x00, 0x13, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x6d, 0x2e, 0x13,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x74,
0x70, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x30, 0x30, 0x31, 0x2e,
0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x63,
0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x63, 0x6f, 0x6d, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
}
packet, err := decodePacket(raw)
require.Nil(t, err)
want := &ReplyNTPSourceName{
ReplyHead: ReplyHead{
Version: protoVersionNumber,
PKTType: pktTypeCmdReply,
Res1: 0,
Res2: 0,
Command: reqNTPSourceName,
Reply: rpyNTPSourceName,
Status: sttSuccess,
Sequence: 3295489555,
},
NTPSourceName: NTPSourceName{
Name: [256]uint8{
// ntp_peer001.sample.facebook.com
0x6e, 0x74, 0x70, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x30, 0x30,
0x31, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x66,
0x61, 0x63, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x63, 0x6f,
0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
},
},
}
require.Equal(t, want, packet)
}

func TestDecodeActivity(t *testing.T) {
raw := []uint8{
0x06, 0x02, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x0c, 0x00, 0x00,
Expand Down

0 comments on commit 80c83be

Please sign in to comment.