stop using tcpip.FullAddress with unix sockets

It's unnecessarily overloading the type, which makes it hard to change the type
in netstack.

PiperOrigin-RevId: 526168235
This commit is contained in:
Kevin Krakauer
2023-04-21 16:48:37 -07:00
committed by gVisor bot
parent 0ce094b9a3
commit 8478fe0a27
11 changed files with 83 additions and 88 deletions
-1
View File
@@ -35,7 +35,6 @@ go_library(
"//pkg/sentry/vfs",
"//pkg/sync",
"//pkg/syserr",
"//pkg/tcpip",
"//pkg/usermem",
"//pkg/waiter",
],
+3 -4
View File
@@ -38,7 +38,6 @@ import (
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/sync"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -124,7 +123,7 @@ func New(t *kernel.Task, skType linux.SockType, protocol Protocol) (*Socket, *sy
// Bind the endpoint for good measure so we can connect to it. The
// bound address will never be exposed.
if err := ep.Bind(tcpip.FullAddress{Addr: "dummy"}); err != nil {
if err := ep.Bind(transport.Address{Addr: "dummy"}); err != nil {
ep.Close(t)
return nil, err
}
@@ -629,7 +628,7 @@ func (s *Socket) sendResponse(ctx context.Context, ms *MessageSet) *syserr.Error
if len(bufs) > 0 {
// RecvMsg never receives the address, so we don't need to send
// one.
_, notify, err := s.connection.Send(ctx, bufs, cms, tcpip.FullAddress{})
_, notify, err := s.connection.Send(ctx, bufs, cms, transport.Address{})
// If the buffer is full, we simply drop messages, just like
// Linux.
if err != nil && err != syserr.ErrWouldBlock {
@@ -656,7 +655,7 @@ func (s *Socket) sendResponse(ctx context.Context, ms *MessageSet) *syserr.Error
// Add the dump_done_errno payload.
m.Put(primitive.AllocateInt64(0))
_, notify, err := s.connection.Send(ctx, [][]byte{m.Finalize()}, cms, tcpip.FullAddress{})
_, notify, err := s.connection.Send(ctx, [][]byte{m.Finalize()}, cms, transport.Address{})
if err != nil && err != syserr.ErrWouldBlock {
return err
}
-8
View File
@@ -301,14 +301,6 @@ var errStackType = syserr.New("expected but did not receive a netstack.Stack", e
// commonEndpoint represents the intersection of a tcpip.Endpoint and a
// transport.Endpoint.
type commonEndpoint interface {
// GetLocalAddress implements tcpip.Endpoint.GetLocalAddress and
// transport.Endpoint.GetLocalAddress.
GetLocalAddress() (tcpip.FullAddress, tcpip.Error)
// GetRemoteAddress implements tcpip.Endpoint.GetRemoteAddress and
// transport.Endpoint.GetRemoteAddress.
GetRemoteAddress() (tcpip.FullAddress, tcpip.Error)
// Readiness implements tcpip.Endpoint.Readiness and
// transport.Endpoint.Readiness.
Readiness(mask waiter.EventMask) waiter.EventMask
-18
View File
@@ -467,24 +467,6 @@ func isLinkLocal(addr tcpip.Address) bool {
// ConvertAddress converts the given address to a native format.
func ConvertAddress(family int, addr tcpip.FullAddress) (linux.SockAddr, uint32) {
switch family {
case linux.AF_UNIX:
var out linux.SockAddrUnix
out.Family = linux.AF_UNIX
l := len([]byte(addr.Addr))
for i := 0; i < l; i++ {
out.Path[i] = int8(addr.Addr[i])
}
// Linux returns the used length of the address struct (including the
// null terminator) for filesystem paths. The Family field is 2 bytes.
// It is sometimes allowed to exclude the null terminator if the
// address length is the max. Abstract and empty paths always return
// the full exact length.
if l == 0 || out.Path[0] == 0 || l == len(out.Path) {
return &out, uint32(2 + l)
}
return &out, uint32(3 + l)
case linux.AF_INET:
var out linux.SockAddrInet
copy(out.Addr[:], addr.Addr)
+1 -2
View File
@@ -18,7 +18,6 @@ import (
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/safemem"
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
"gvisor.dev/gvisor/pkg/tcpip"
)
// EndpointWriter implements safemem.Writer that writes to a transport.Endpoint.
@@ -79,7 +78,7 @@ type EndpointReader struct {
MsgSize int64
// From, if not nil, will be set with the address read from.
From *tcpip.FullAddress
From *transport.Address
// Control contains the received control messages.
Control transport.ControlMessages
@@ -50,7 +50,7 @@ type ConnectingEndpoint interface {
Type() linux.SockType
// GetLocalAddress returns the bound path.
GetLocalAddress() (tcpip.FullAddress, tcpip.Error)
GetLocalAddress() (Address, tcpip.Error)
// Locker protects the following methods. While locked, only the holder of
// the lock can change the return value of the protected methods.
@@ -438,7 +438,7 @@ func (e *connectionedEndpoint) Listen(ctx context.Context, backlog int) *syserr.
}
// Accept accepts a new connection.
func (e *connectionedEndpoint) Accept(ctx context.Context, peerAddr *tcpip.FullAddress) (Endpoint, *syserr.Error) {
func (e *connectionedEndpoint) Accept(ctx context.Context, peerAddr *Address) (Endpoint, *syserr.Error) {
e.Lock()
if !e.ListeningLocked() {
@@ -511,7 +511,7 @@ func (e *connectionedEndpoint) getAcceptedEndpointLocked(ctx context.Context) (*
//
// Bind will fail only if the socket is connected, bound or the passed address
// is invalid (the empty string).
func (e *connectionedEndpoint) Bind(addr tcpip.FullAddress) *syserr.Error {
func (e *connectionedEndpoint) Bind(addr Address) *syserr.Error {
e.Lock()
defer e.Unlock()
if e.isBound() || e.ListeningLocked() {
@@ -523,7 +523,7 @@ func (e *connectionedEndpoint) Bind(addr tcpip.FullAddress) *syserr.Error {
}
// Save the bound address.
e.path = string(addr.Addr)
e.path = addr.Addr
return nil
}
@@ -18,7 +18,6 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -115,7 +114,7 @@ func (e *connectionlessEndpoint) SendMsg(ctx context.Context, data [][]byte, c C
defer connected.Release(ctx)
e.Lock()
n, notify, err := connected.Send(ctx, data, c, tcpip.FullAddress{Addr: tcpip.Address(e.path)})
n, notify, err := connected.Send(ctx, data, c, Address{Addr: e.path})
e.Unlock()
var notifyFn func()
@@ -154,7 +153,7 @@ func (*connectionlessEndpoint) Listen(context.Context, int) *syserr.Error {
}
// Accept accepts a new connection.
func (*connectionlessEndpoint) Accept(context.Context, *tcpip.FullAddress) (Endpoint, *syserr.Error) {
func (*connectionlessEndpoint) Accept(context.Context, *Address) (Endpoint, *syserr.Error) {
return nil, syserr.ErrNotSupported
}
@@ -166,7 +165,7 @@ func (*connectionlessEndpoint) Accept(context.Context, *tcpip.FullAddress) (Endp
//
// Bind will fail only if the socket is connected, bound or the passed address
// is invalid (the empty string).
func (e *connectionlessEndpoint) Bind(addr tcpip.FullAddress) *syserr.Error {
func (e *connectionlessEndpoint) Bind(addr Address) *syserr.Error {
e.Lock()
defer e.Unlock()
if e.isBound() {
@@ -178,7 +177,7 @@ func (e *connectionlessEndpoint) Bind(addr tcpip.FullAddress) *syserr.Error {
}
// Save the bound address.
e.path = string(addr.Addr)
e.path = addr.Addr
return nil
}
+9 -9
View File
@@ -149,7 +149,7 @@ func (c *HostConnectedEndpoint) SockType() linux.SockType {
}
// Send implements ConnectedEndpoint.Send.
func (c *HostConnectedEndpoint) Send(ctx context.Context, data [][]byte, controlMessages ControlMessages, from tcpip.FullAddress) (int64, bool, *syserr.Error) {
func (c *HostConnectedEndpoint) Send(ctx context.Context, data [][]byte, controlMessages ControlMessages, from Address) (int64, bool, *syserr.Error) {
c.mu.RLock()
defer c.mu.RUnlock()
@@ -212,8 +212,8 @@ func (c *HostConnectedEndpoint) Passcred() bool {
}
// GetLocalAddress implements ConnectedEndpoint.GetLocalAddress.
func (c *HostConnectedEndpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) {
return tcpip.FullAddress{Addr: tcpip.Address(c.addr)}, nil
func (c *HostConnectedEndpoint) GetLocalAddress() (Address, tcpip.Error) {
return Address{Addr: c.addr}, nil
}
// EventUpdate implements ConnectedEndpoint.EventUpdate.
@@ -229,7 +229,7 @@ func (c *HostConnectedEndpoint) EventUpdate() error {
}
// Recv implements Receiver.Recv.
func (c *HostConnectedEndpoint) Recv(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool) (int64, int64, ControlMessages, bool, tcpip.FullAddress, bool, *syserr.Error) {
func (c *HostConnectedEndpoint) Recv(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool) (int64, int64, ControlMessages, bool, Address, bool, *syserr.Error) {
c.mu.RLock()
defer c.mu.RUnlock()
@@ -248,7 +248,7 @@ func (c *HostConnectedEndpoint) Recv(ctx context.Context, data [][]byte, creds b
err = nil
}
if err != nil {
return 0, 0, ControlMessages{}, false, tcpip.FullAddress{}, false, syserr.FromError(err)
return 0, 0, ControlMessages{}, false, Address{}, false, syserr.FromError(err)
}
// There is no need for the callee to call RecvNotify because fdReadVec uses
@@ -261,18 +261,18 @@ func (c *HostConnectedEndpoint) Recv(ctx context.Context, data [][]byte, creds b
// Avoid extra allocations in the case where there isn't any control data.
if len(cm) == 0 {
return rl, ml, ControlMessages{}, cTrunc, tcpip.FullAddress{Addr: tcpip.Address(c.addr)}, false, nil
return rl, ml, ControlMessages{}, cTrunc, Address{Addr: c.addr}, false, nil
}
fds, err := cm.ExtractFDs()
if err != nil {
return 0, 0, ControlMessages{}, false, tcpip.FullAddress{}, false, syserr.FromError(err)
return 0, 0, ControlMessages{}, false, Address{}, false, syserr.FromError(err)
}
if len(fds) == 0 {
return rl, ml, ControlMessages{}, cTrunc, tcpip.FullAddress{Addr: tcpip.Address(c.addr)}, false, nil
return rl, ml, ControlMessages{}, cTrunc, Address{Addr: c.addr}, false, nil
}
return rl, ml, ControlMessages{Rights: &SCMRights{fds}}, cTrunc, tcpip.FullAddress{Addr: tcpip.Address(c.addr)}, false, nil
return rl, ml, ControlMessages{Rights: &SCMRights{fds}}, cTrunc, Address{Addr: c.addr}, false, nil
}
// RecvNotify implements Receiver.RecvNotify.
+1 -2
View File
@@ -17,7 +17,6 @@ package transport
import (
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -113,7 +112,7 @@ func (q *queue) IsWritable() bool {
//
// If notify is true, ReaderQueue.Notify must be called:
// q.ReaderQueue.Notify(waiter.ReadableEvents)
func (q *queue) Enqueue(ctx context.Context, data [][]byte, c ControlMessages, from tcpip.FullAddress, discardEmpty bool, truncate bool) (l int64, notify bool, err *syserr.Error) {
func (q *queue) Enqueue(ctx context.Context, data [][]byte, c ControlMessages, from Address, discardEmpty bool, truncate bool) (l int64, notify bool, err *syserr.Error) {
q.mu.Lock()
if q.closed {
+30 -23
View File
@@ -131,7 +131,7 @@ type Endpoint interface {
//
// If set, notify is a callback that should be called after RecvMesg
// completes without mm.activeMu held.
RecvMsg(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool, addr *tcpip.FullAddress) (recvLen, msgLen int64, cm ControlMessages, CMTruncated bool, notify func(), err *syserr.Error)
RecvMsg(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool, addr *Address) (recvLen, msgLen int64, cm ControlMessages, CMTruncated bool, notify func(), err *syserr.Error)
// SendMsg writes data and a control message to the endpoint's peer.
// This method does not block if the data cannot be written.
@@ -166,22 +166,22 @@ type Endpoint interface {
//
// peerAddr if not nil will be populated with the address of the connected
// peer on a successful accept.
Accept(ctx context.Context, peerAddr *tcpip.FullAddress) (Endpoint, *syserr.Error)
Accept(ctx context.Context, peerAddr *Address) (Endpoint, *syserr.Error)
// Bind binds the endpoint to a specific local address and port.
// Specifying a NIC is optional.
Bind(address tcpip.FullAddress) *syserr.Error
Bind(address Address) *syserr.Error
// Type return the socket type, typically either SockStream, SockDgram
// or SockSeqpacket.
Type() linux.SockType
// GetLocalAddress returns the address to which the endpoint is bound.
GetLocalAddress() (tcpip.FullAddress, tcpip.Error)
GetLocalAddress() (Address, tcpip.Error)
// GetRemoteAddress returns the address to which the endpoint is
// connected.
GetRemoteAddress() (tcpip.FullAddress, tcpip.Error)
GetRemoteAddress() (Address, tcpip.Error)
// SetSockOpt sets a socket option.
SetSockOpt(opt tcpip.SettableSocketOption) tcpip.Error
@@ -312,7 +312,7 @@ type message struct {
//
// If the endpoint that sent the message is not bound, the Address is
// the empty string.
Address tcpip.FullAddress
Address Address
}
// Length returns number of bytes stored in the message.
@@ -344,7 +344,7 @@ type Receiver interface {
// See Endpoint.RecvMsg for documentation on shared arguments.
//
// notify indicates if RecvNotify should be called.
Recv(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool) (recvLen, msgLen int64, cm ControlMessages, CMTruncated bool, source tcpip.FullAddress, notify bool, err *syserr.Error)
Recv(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool) (recvLen, msgLen int64, cm ControlMessages, CMTruncated bool, source Address, notify bool, err *syserr.Error)
// RecvNotify notifies the Receiver of a successful Recv. This must not be
// called while holding any endpoint locks.
@@ -376,6 +376,13 @@ type Receiver interface {
Release(ctx context.Context)
}
// Address is a unix socket address.
//
// +stateify savable
type Address struct {
Addr string
}
// queueReceiver implements Receiver for datagram sockets.
//
// +stateify savable
@@ -384,7 +391,7 @@ type queueReceiver struct {
}
// Recv implements Receiver.Recv.
func (q *queueReceiver) Recv(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool) (int64, int64, ControlMessages, bool, tcpip.FullAddress, bool, *syserr.Error) {
func (q *queueReceiver) Recv(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool) (int64, int64, ControlMessages, bool, Address, bool, *syserr.Error) {
var m *message
var notify bool
var err *syserr.Error
@@ -394,7 +401,7 @@ func (q *queueReceiver) Recv(ctx context.Context, data [][]byte, creds bool, num
m, notify, err = q.readQueue.Dequeue()
}
if err != nil {
return 0, 0, ControlMessages{}, false, tcpip.FullAddress{}, false, err
return 0, 0, ControlMessages{}, false, Address{}, false, err
}
src := []byte(m.Data)
var copied int64
@@ -451,7 +458,7 @@ type streamQueueReceiver struct {
mu streamQueueReceiverMutex `state:"nosave"`
buffer []byte
control ControlMessages
addr tcpip.FullAddress
addr Address
}
func vecCopy(data [][]byte, buf []byte) (int64, [][]byte, []byte) {
@@ -496,7 +503,7 @@ func (q *streamQueueReceiver) RecvMaxQueueSize() int64 {
}
// Recv implements Receiver.Recv.
func (q *streamQueueReceiver) Recv(ctx context.Context, data [][]byte, wantCreds bool, numRights int, peek bool) (int64, int64, ControlMessages, bool, tcpip.FullAddress, bool, *syserr.Error) {
func (q *streamQueueReceiver) Recv(ctx context.Context, data [][]byte, wantCreds bool, numRights int, peek bool) (int64, int64, ControlMessages, bool, Address, bool, *syserr.Error) {
q.mu.Lock()
defer q.mu.Unlock()
@@ -509,7 +516,7 @@ func (q *streamQueueReceiver) Recv(ctx context.Context, data [][]byte, wantCreds
// the next time Recv() is called.
m, n, err := q.readQueue.Dequeue()
if err != nil {
return 0, 0, ControlMessages{}, false, tcpip.FullAddress{}, false, err
return 0, 0, ControlMessages{}, false, Address{}, false, err
}
notify = n
q.buffer = []byte(m.Data)
@@ -620,7 +627,7 @@ type ConnectedEndpoint interface {
Passcred() bool
// GetLocalAddress implements Endpoint.GetLocalAddress.
GetLocalAddress() (tcpip.FullAddress, tcpip.Error)
GetLocalAddress() (Address, tcpip.Error)
// Send sends a single message. This method does not block.
//
@@ -628,7 +635,7 @@ type ConnectedEndpoint interface {
//
// syserr.ErrWouldBlock can be returned along with a partial write if
// the caller should block to send the rest of the data.
Send(ctx context.Context, data [][]byte, c ControlMessages, from tcpip.FullAddress) (n int64, notify bool, err *syserr.Error)
Send(ctx context.Context, data [][]byte, c ControlMessages, from Address) (n int64, notify bool, err *syserr.Error)
// SendNotify notifies the ConnectedEndpoint of a successful Send. This
// must not be called while holding any endpoint locks.
@@ -684,7 +691,7 @@ type connectedEndpoint struct {
Passcred() bool
// GetLocalAddress implements Endpoint.GetLocalAddress.
GetLocalAddress() (tcpip.FullAddress, tcpip.Error)
GetLocalAddress() (Address, tcpip.Error)
// Type implements Endpoint.Type.
Type() linux.SockType
@@ -699,12 +706,12 @@ func (e *connectedEndpoint) Passcred() bool {
}
// GetLocalAddress implements ConnectedEndpoint.GetLocalAddress.
func (e *connectedEndpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) {
func (e *connectedEndpoint) GetLocalAddress() (Address, tcpip.Error) {
return e.endpoint.GetLocalAddress()
}
// Send implements ConnectedEndpoint.Send.
func (e *connectedEndpoint) Send(ctx context.Context, data [][]byte, c ControlMessages, from tcpip.FullAddress) (int64, bool, *syserr.Error) {
func (e *connectedEndpoint) Send(ctx context.Context, data [][]byte, c ControlMessages, from Address) (int64, bool, *syserr.Error) {
discardEmpty := false
truncate := false
if e.endpoint.Type() == linux.SOCK_STREAM {
@@ -852,7 +859,7 @@ func (e *baseEndpoint) Connected() bool {
}
// RecvMsg reads data and a control message from the endpoint.
func (e *baseEndpoint) RecvMsg(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool, addr *tcpip.FullAddress) (int64, int64, ControlMessages, bool, func(), *syserr.Error) {
func (e *baseEndpoint) RecvMsg(ctx context.Context, data [][]byte, creds bool, numRights int, peek bool, addr *Address) (int64, int64, ControlMessages, bool, func(), *syserr.Error) {
e.Lock()
receiver := e.receiver
@@ -892,7 +899,7 @@ func (e *baseEndpoint) SendMsg(ctx context.Context, data [][]byte, c ControlMess
}
connected := e.connected
n, notify, err := connected.Send(ctx, data, c, tcpip.FullAddress{Addr: tcpip.Address(e.path)})
n, notify, err := connected.Send(ctx, data, c, Address{Addr: e.path})
e.Unlock()
var notifyFn func()
@@ -999,22 +1006,22 @@ func (e *baseEndpoint) Shutdown(flags tcpip.ShutdownFlags) *syserr.Error {
}
// GetLocalAddress returns the bound path.
func (e *baseEndpoint) GetLocalAddress() (tcpip.FullAddress, tcpip.Error) {
func (e *baseEndpoint) GetLocalAddress() (Address, tcpip.Error) {
e.Lock()
defer e.Unlock()
return tcpip.FullAddress{Addr: tcpip.Address(e.path)}, nil
return Address{Addr: e.path}, nil
}
// GetRemoteAddress returns the local address of the connected endpoint (if
// available).
func (e *baseEndpoint) GetRemoteAddress() (tcpip.FullAddress, tcpip.Error) {
func (e *baseEndpoint) GetRemoteAddress() (Address, tcpip.Error) {
e.Lock()
c := e.connected
e.Unlock()
if c != nil {
return c.GetLocalAddress()
}
return tcpip.FullAddress{}, &tcpip.ErrNotConnected{}
return Address{}, &tcpip.ErrNotConnected{}
}
// Release implements BoundEndpoint.Release.
+31 -12
View File
@@ -37,7 +37,6 @@ import (
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
"gvisor.dev/gvisor/pkg/sentry/vfs"
"gvisor.dev/gvisor/pkg/syserr"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -132,7 +131,7 @@ func (s *Socket) GetSockOpt(t *kernel.Task, level, name int, outPtr hostarch.Add
// blockingAccept implements a blocking version of accept(2), that is, if no
// connections are ready to be accept, it will block until one becomes ready.
func (s *Socket) blockingAccept(t *kernel.Task, peerAddr *tcpip.FullAddress) (transport.Endpoint, *syserr.Error) {
func (s *Socket) blockingAccept(t *kernel.Task, peerAddr *transport.Address) (transport.Endpoint, *syserr.Error) {
// Register for notifications.
e, ch := waiter.NewChannelEntry(waiter.ReadableEvents)
s.EventRegister(&e)
@@ -154,9 +153,9 @@ func (s *Socket) blockingAccept(t *kernel.Task, peerAddr *tcpip.FullAddress) (tr
// Accept implements the linux syscall accept(2) for sockets backed by
// a transport.Endpoint.
func (s *Socket) Accept(t *kernel.Task, peerRequested bool, flags int, blocking bool) (int32, linux.SockAddr, uint32, *syserr.Error) {
var peerAddr *tcpip.FullAddress
var peerAddr *transport.Address
if peerRequested {
peerAddr = &tcpip.FullAddress{}
peerAddr = &transport.Address{}
}
ep, err := s.ep.Accept(t, peerAddr)
if err != nil {
@@ -184,7 +183,7 @@ func (s *Socket) Accept(t *kernel.Task, peerRequested bool, flags int, blocking
var addr linux.SockAddr
var addrLen uint32
if peerAddr != nil {
addr, addrLen = socket.ConvertAddress(linux.AF_UNIX, *peerAddr)
addr, addrLen = convertAddress(*peerAddr)
}
fd, e := t.NewFDFrom(0, ns, kernel.FDFlags{
@@ -222,7 +221,7 @@ func (s *Socket) Bind(t *kernel.Task, sockaddr []byte) *syserr.Error {
// syserr.ErrPortInUse corresponds to EADDRINUSE.
return syserr.ErrPortInUse
}
if err := s.ep.Bind(tcpip.FullAddress{Addr: tcpip.Address(p)}); err != nil {
if err := s.ep.Bind(transport.Address{Addr: p}); err != nil {
asn.Remove(name, s)
return err
}
@@ -261,7 +260,7 @@ func (s *Socket) Bind(t *kernel.Task, sockaddr []byte) *syserr.Error {
if err != nil {
return syserr.FromError(err)
}
if err := s.ep.Bind(tcpip.FullAddress{Addr: tcpip.Address(p)}); err != nil {
if err := s.ep.Bind(transport.Address{Addr: p}); err != nil {
if unlinkErr := t.Kernel().VFS().UnlinkAt(t, t.Credentials(), &pop); unlinkErr != nil {
log.Warningf("failed to unlink socket file created for bind(%q): %v", p, unlinkErr)
}
@@ -469,7 +468,7 @@ func (s *Socket) GetPeerName(t *kernel.Task) (linux.SockAddr, uint32, *syserr.Er
return nil, 0, syserr.TranslateNetstackError(err)
}
a, l := socket.ConvertAddress(linux.AF_UNIX, addr)
a, l := convertAddress(addr)
return a, l, nil
}
@@ -481,7 +480,7 @@ func (s *Socket) GetSockName(t *kernel.Task) (linux.SockAddr, uint32, *syserr.Er
return nil, 0, syserr.TranslateNetstackError(err)
}
a, l := socket.ConvertAddress(linux.AF_UNIX, addr)
a, l := convertAddress(addr)
return a, l, nil
}
@@ -709,7 +708,7 @@ func (s *Socket) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, have
Peek: peek,
}
if senderRequested {
r.From = &tcpip.FullAddress{}
r.From = &transport.Address{}
}
doRead := func() (int64, error) {
@@ -739,7 +738,7 @@ func (s *Socket) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, have
var from linux.SockAddr
var fromLen uint32
if r.From != nil && len([]byte(r.From.Addr)) != 0 {
from, fromLen = socket.ConvertAddress(linux.AF_UNIX, *r.From)
from, fromLen = convertAddress(*r.From)
}
if r.ControlTrunc {
@@ -774,7 +773,7 @@ func (s *Socket) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, have
var from linux.SockAddr
var fromLen uint32
if r.From != nil {
from, fromLen = socket.ConvertAddress(linux.AF_UNIX, *r.From)
from, fromLen = convertAddress(*r.From)
}
if r.ControlTrunc {
@@ -826,6 +825,26 @@ func (s *Socket) Type() (family int, skType linux.SockType, protocol int) {
return linux.AF_UNIX, s.stype, 0
}
func convertAddress(addr transport.Address) (linux.SockAddr, uint32) {
var out linux.SockAddrUnix
out.Family = linux.AF_UNIX
l := len([]byte(addr.Addr))
for i := 0; i < l; i++ {
out.Path[i] = int8(addr.Addr[i])
}
// Linux returns the used length of the address struct (including the
// null terminator) for filesystem paths. The Family field is 2 bytes.
// It is sometimes allowed to exclude the null terminator if the
// address length is the max. Abstract and empty paths always return
// the full exact length.
if l == 0 || out.Path[0] == 0 || l == len(out.Path) {
return &out, uint32(2 + l)
}
return &out, uint32(3 + l)
}
func init() {
socket.RegisterProvider(linux.AF_UNIX, &provider{})
}