xref: /aosp_15_r20/external/cronet/net/socket/unix_domain_server_socket_posix.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_SOCKET_UNIX_DOMAIN_SERVER_SOCKET_POSIX_H_
6 #define NET_SOCKET_UNIX_DOMAIN_SERVER_SOCKET_POSIX_H_
7 
8 #include <stdint.h>
9 #include <sys/types.h>
10 
11 #include <memory>
12 #include <string>
13 
14 #include "base/functional/callback.h"
15 #include "base/memory/raw_ptr.h"
16 #include "build/build_config.h"
17 #include "net/base/completion_once_callback.h"
18 #include "net/base/net_export.h"
19 #include "net/socket/server_socket.h"
20 #include "net/socket/socket_descriptor.h"
21 
22 namespace net {
23 
24 class SocketPosix;
25 
26 // A server socket that uses unix domain socket as the transport layer.
27 // Supports abstract namespaces on Linux and Android.
28 class NET_EXPORT UnixDomainServerSocket : public ServerSocket {
29  public:
30   // Credentials of a peer process connected to the socket.
31   struct NET_EXPORT Credentials {
32 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
33     BUILDFLAG(IS_FUCHSIA)
34     // Linux and Fuchsia provide more information about the connected peer
35     // than Windows/OS X. It's useful for permission-based authorization on
36     // Android.
37     pid_t process_id;
38 #endif
39     uid_t user_id;
40     gid_t group_id;
41   };
42 
43   // Callback that returns whether the already connected client, identified by
44   // its credentials, is allowed to keep the connection open. Note that
45   // the socket is closed immediately in case the callback returns false.
46   using AuthCallback = base::RepeatingCallback<bool(const Credentials&)>;
47 
48   UnixDomainServerSocket(const AuthCallback& auth_callack,
49                          bool use_abstract_namespace);
50 
51   UnixDomainServerSocket(const UnixDomainServerSocket&) = delete;
52   UnixDomainServerSocket& operator=(const UnixDomainServerSocket&) = delete;
53 
54   ~UnixDomainServerSocket() override;
55 
56   // Gets credentials of peer to check permissions.
57   static bool GetPeerCredentials(SocketDescriptor socket_fd,
58                                  Credentials* credentials);
59 
60   // ServerSocket implementation.
61   int Listen(const IPEndPoint& address,
62              int backlog,
63              std::optional<bool> ipv6_only) override;
64   int ListenWithAddressAndPort(const std::string& address_string,
65                                uint16_t port,
66                                int backlog) override;
67   int GetLocalAddress(IPEndPoint* address) const override;
68   int Accept(std::unique_ptr<StreamSocket>* socket,
69              CompletionOnceCallback callback) override;
70 
71   // Creates a server socket, binds it to the specified |socket_path| and
72   // starts listening for incoming connections with the specified |backlog|.
73   int BindAndListen(const std::string& socket_path, int backlog);
74 
75   // Accepts an incoming connection on |listen_socket_|, but passes back
76   // a raw SocketDescriptor instead of a StreamSocket.
77   int AcceptSocketDescriptor(SocketDescriptor* socket_descriptor,
78                              CompletionOnceCallback callback);
79 
80  private:
81   int DoAccept();
82   void AcceptCompleted(int rv);
83   bool AuthenticateAndGetStreamSocket();
84   void SetSocketResult(std::unique_ptr<SocketPosix> accepted_socket);
85   void RunCallback(int rv);
86   void CancelCallback();
87 
88   std::unique_ptr<SocketPosix> listen_socket_;
89   const AuthCallback auth_callback_;
90   CompletionOnceCallback callback_;
91   const bool use_abstract_namespace_;
92 
93   std::unique_ptr<SocketPosix> accept_socket_;
94 
95   struct SocketDestination {
96     // Non-null while a call to Accept is pending.
97     raw_ptr<std::unique_ptr<StreamSocket>> stream = nullptr;
98 
99     // Non-null while a call to AcceptSocketDescriptor is pending.
100     raw_ptr<SocketDescriptor> descriptor = nullptr;
101   };
102   SocketDestination out_socket_;
103 };
104 
105 }  // namespace net
106 
107 #endif  // NET_SOCKET_UNIX_DOMAIN_SERVER_SOCKET_POSIX_H_
108