summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/socket/control
diff options
context:
space:
mode:
authorIan Gudger <igudger@google.com>2018-05-01 22:11:07 -0700
committerShentubot <shentubot@google.com>2018-05-01 22:11:49 -0700
commit3d3deef573a54e031cb98038b9f617f5fac31044 (patch)
tree9ed71c29dbabc80845a6b7e5510717cad354c309 /pkg/sentry/socket/control
parent185233427b3834086a9050336113f9e22176fa3b (diff)
Implement SO_TIMESTAMP
PiperOrigin-RevId: 195047018 Change-Id: I6d99528a00a2125f414e1e51e067205289ec9d3d
Diffstat (limited to 'pkg/sentry/socket/control')
-rw-r--r--pkg/sentry/socket/control/control.go35
1 files changed, 35 insertions, 0 deletions
diff --git a/pkg/sentry/socket/control/control.go b/pkg/sentry/socket/control/control.go
index cb34cbc85..17ecdd11c 100644
--- a/pkg/sentry/socket/control/control.go
+++ b/pkg/sentry/socket/control/control.go
@@ -208,6 +208,31 @@ func putCmsg(buf []byte, msgType uint32, align uint, data []int32) []byte {
return alignSlice(buf, align)
}
+func putCmsgStruct(buf []byte, msgType uint32, align uint, data interface{}) []byte {
+ if cap(buf)-len(buf) < linux.SizeOfControlMessageHeader {
+ return buf
+ }
+ ob := buf
+
+ buf = putUint64(buf, uint64(linux.SizeOfControlMessageHeader))
+ buf = putUint32(buf, linux.SOL_SOCKET)
+ buf = putUint32(buf, msgType)
+
+ hdrBuf := buf
+
+ buf = binary.Marshal(buf, usermem.ByteOrder, data)
+
+ // Check if we went over.
+ if cap(buf) != cap(ob) {
+ return hdrBuf
+ }
+
+ // Fix up length.
+ putUint64(ob, uint64(len(buf)-len(ob)))
+
+ return alignSlice(buf, align)
+}
+
// Credentials implements SCMCredentials.Credentials.
func (c *scmCredentials) Credentials(t *kernel.Task) (kernel.ThreadID, auth.UID, auth.GID) {
// "When a process's user and group IDs are passed over a UNIX domain
@@ -261,6 +286,16 @@ func alignSlice(buf []byte, align uint) []byte {
return buf[:aligned]
}
+// PackTimestamp packs a SO_TIMESTAMP socket control message.
+func PackTimestamp(t *kernel.Task, timestamp int64, buf []byte) []byte {
+ return putCmsgStruct(
+ buf,
+ linux.SO_TIMESTAMP,
+ t.Arch().Width(),
+ linux.NsecToTimeval(timestamp),
+ )
+}
+
// Parse parses a raw socket control message into portable objects.
func Parse(t *kernel.Task, socketOrEndpoint interface{}, buf []byte) (unix.ControlMessages, error) {
var (