diff options
author | Jamie Liu <jamieliu@google.com> | 2019-07-31 12:54:49 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2019-07-31 12:56:04 -0700 |
commit | cbe145247a748177e62b268f402cbe76e5b1ca35 (patch) | |
tree | 079949c800a6f8f50f242f559a302f73f9c8fa7e /pkg/flipcall/flipcall_unsafe.go | |
parent | cf2b2d97d512a91261f72abe40b163c61d52705f (diff) |
Flipcall refinements.
Note that some of these changes affect the protocol in
backward-incompatible ways.
- Replace use of "initially-active" and "initially-inactive" with
"client" and "server" respectively for clarity.
- Fix a race condition involving Endpoint.Shutdown() by repeatedly
invoking FUTEX_WAKE until it is confirmed that no local thread is
blocked in FUTEX_WAIT.
- Drop flipcall.ControlMode.
PiperOrigin-RevId: 260981382
Diffstat (limited to 'pkg/flipcall/flipcall_unsafe.go')
-rw-r--r-- | pkg/flipcall/flipcall_unsafe.go | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/pkg/flipcall/flipcall_unsafe.go b/pkg/flipcall/flipcall_unsafe.go new file mode 100644 index 000000000..7c8977893 --- /dev/null +++ b/pkg/flipcall/flipcall_unsafe.go @@ -0,0 +1,69 @@ +// Copyright 2019 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package flipcall + +import ( + "reflect" + "unsafe" +) + +// Packets consist of an 8-byte header followed by an arbitrarily-sized +// datagram. The header consists of: +// +// - A 4-byte native-endian connection state. +// +// - A 4-byte native-endian datagram length in bytes. +const ( + sizeofUint32 = unsafe.Sizeof(uint32(0)) + + // PacketHeaderBytes is the size of a flipcall packet header in bytes. The + // maximum datagram size supported by a flipcall connection is equal to the + // length of the packet window minus PacketHeaderBytes. + // + // PacketHeaderBytes is exported to support its use in constant + // expressions. Non-constant expressions may prefer to use + // PacketWindowLengthForDataCap(). + PacketHeaderBytes = 2 * sizeofUint32 +) + +func (ep *Endpoint) connState() *uint32 { + return (*uint32)((unsafe.Pointer)(ep.packet)) +} + +func (ep *Endpoint) dataLen() *uint32 { + return (*uint32)((unsafe.Pointer)(ep.packet + sizeofUint32)) +} + +// Data returns the datagram part of ep's packet window as a byte slice. +// +// Note that the packet window is shared with the potentially-untrusted peer +// Endpoint, which may concurrently mutate the contents of the packet window. +// Thus: +// +// - Readers must not assume that two reads of the same byte in Data() will +// return the same result. In other words, readers should read any given byte +// in Data() at most once. +// +// - Writers must not assume that they will read back the same data that they +// have written. In other words, writers should avoid reading from Data() at +// all. +func (ep *Endpoint) Data() []byte { + var bs []byte + bsReflect := (*reflect.SliceHeader)((unsafe.Pointer)(&bs)) + bsReflect.Data = ep.packet + PacketHeaderBytes + bsReflect.Len = int(ep.dataCap) + bsReflect.Cap = int(ep.dataCap) + return bs +} |