@@ -106,6 +106,14 @@ type connectionedEndpoint struct {
106106 // tcpip.SockStream.
107107 stype linux.SockType
108108
109+ // peerCreds is used to store the peer credentials.
110+ // This will store the socket's own credentials until the connection is
111+ // established with connect(2). Once the connection is established, this
112+ // will store the peer's credentials. The use of this option is possible
113+ // only for connected `AF_UNIX` stream sockets and for `AF_UNIX` stream and
114+ // datagram socket pairs created using socketpair(2)
115+ peerCreds CredentialsControlMessage
116+
109117 // acceptedChan is per the TCP endpoint implementation. Note that the
110118 // sockets in this channel are _already in the connected state_, and
111119 // have another associated connectionedEndpoint.
@@ -274,6 +282,16 @@ func (e *connectionedEndpoint) Close(ctx context.Context) {
274282 }
275283}
276284
285+ func (e * connectionedEndpoint ) swapPeerCredsLocked (ctx context.Context , cend ConnectingEndpoint , ne * connectionedEndpoint ) * syserr.Error {
286+ ce , ok := cend .(* connectionedEndpoint )
287+ if ! ok {
288+ return syserr .ErrInvalidEndpointState
289+ }
290+ // Swap peer credentials between the two endpoints.
291+ ne .peerCreds , ce .peerCreds = ce .peerCreds , ne .peerCreds
292+ return nil
293+ }
294+
277295// BidirectionalConnect implements BoundEndpoint.BidirectionalConnect.
278296func (e * connectionedEndpoint ) BidirectionalConnect (ctx context.Context , ce ConnectingEndpoint , returnConnect func (Receiver , ConnectedEndpoint ), opts UnixSocketOpts ) * syserr.Error {
279297 if ce .Type () != e .stype {
@@ -327,6 +345,7 @@ func (e *connectionedEndpoint) BidirectionalConnect(ctx context.Context, ce Conn
327345 ne .ops .SetSendBufferSize (defaultBufferSize , false /* notify */ )
328346 ne .ops .SetReceiveBufferSize (defaultBufferSize , false /* notify */ )
329347 ne .SocketOptions ().SetPassCred (e .SocketOptions ().GetPassCred ())
348+ ne .peerCreds = e .peerCreds
330349
331350 readQueue := & queue {ReaderQueue : ce .WaiterQueue (), WriterQueue : ne .Queue , limit : defaultBufferSize }
332351 readQueue .InitRefs ()
@@ -354,6 +373,9 @@ func (e *connectionedEndpoint) BidirectionalConnect(ctx context.Context, ce Conn
354373 }
355374 readQueue .IncRef ()
356375 if e .stype == linux .SOCK_STREAM {
376+ if err := e .swapPeerCredsLocked (ctx , ce , ne ); err != nil {
377+ return err
378+ }
357379 returnConnect (& streamQueueReceiver {queueReceiver : queueReceiver {readQueue : readQueue }}, connected )
358380 } else {
359381 returnConnect (& queueReceiver {readQueue : readQueue }, connected )
@@ -655,3 +677,15 @@ func (e *connectionedEndpoint) EventUnregister(we *waiter.Entry) {
655677func (e * connectionedEndpoint ) GetAcceptConn () bool {
656678 return e .Listening ()
657679}
680+
681+ func (e * connectionedEndpoint ) PeerCreds () CredentialsControlMessage {
682+ e .Lock ()
683+ defer e .Unlock ()
684+ return e .peerCreds
685+ }
686+
687+ func (e * connectionedEndpoint ) SetPeerCreds (creds CredentialsControlMessage ) {
688+ e .Lock ()
689+ defer e .Unlock ()
690+ e .peerCreds = creds
691+ }
0 commit comments